Initial WebM release
[platform/upstream/libvpx.git] / vp8 / encoder / arm / neon / variance_neon.asm
1 ;
2 ;  Copyright (c) 2010 The VP8 project authors. All Rights Reserved.
3 ;
4 ;  Use of this source code is governed by a BSD-style license and patent
5 ;  grant that can be found in the LICENSE file in the root of the source
6 ;  tree. All contributing project authors may be found in the AUTHORS
7 ;  file in the root of the source tree.
8 ;
9
10
11     EXPORT  |vp8_variance16x16_neon|
12     EXPORT  |vp8_variance16x8_neon|
13     EXPORT  |vp8_variance8x16_neon|
14     EXPORT  |vp8_variance8x8_neon|
15
16     ARM
17     REQUIRE8
18     PRESERVE8
19
20     AREA ||.text||, CODE, READONLY, ALIGN=2
21
22 ; r0    unsigned char *src_ptr
23 ; r1    int source_stride
24 ; r2    unsigned char *ref_ptr
25 ; r3    int  recon_stride
26 ; stack unsigned int *sse
27 |vp8_variance16x16_neon| PROC
28     vmov.i8         q8, #0                      ;q8 - sum
29     vmov.i8         q9, #0                      ;q9, q10 - sse
30     vmov.i8         q10, #0
31
32     mov             r12, #8
33
34 variance16x16_neon_loop
35     vld1.8          {q0}, [r0], r1              ;Load up source and reference
36     vld1.8          {q2}, [r2], r3
37     vld1.8          {q1}, [r0], r1
38     vld1.8          {q3}, [r2], r3
39
40     vsubl.u8        q11, d0, d4                 ;calculate diff
41     vsubl.u8        q12, d1, d5
42     vsubl.u8        q13, d2, d6
43     vsubl.u8        q14, d3, d7
44
45     ;VPADAL adds adjacent pairs of elements of a vector, and accumulates
46     ;the results into the elements of the destination vector. The explanation
47     ;in ARM guide is wrong.
48     vpadal.s16      q8, q11                     ;calculate sum
49     vmlal.s16       q9, d22, d22                ;calculate sse
50     vmlal.s16       q10, d23, d23
51
52     subs            r12, r12, #1
53
54     vpadal.s16      q8, q12
55     vmlal.s16       q9, d24, d24
56     vmlal.s16       q10, d25, d25
57     vpadal.s16      q8, q13
58     vmlal.s16       q9, d26, d26
59     vmlal.s16       q10, d27, d27
60     vpadal.s16      q8, q14
61     vmlal.s16       q9, d28, d28
62     vmlal.s16       q10, d29, d29
63
64     bne             variance16x16_neon_loop
65
66     vadd.u32        q10, q9, q10                ;accumulate sse
67     vpaddl.s32      q0, q8                      ;accumulate sum
68
69     ldr             r12, [sp]                   ;load *sse from stack
70
71     vpaddl.u32      q1, q10
72     vadd.s64        d0, d0, d1
73     vadd.u64        d1, d2, d3
74
75     ;vmov.32        r0, d0[0]                   ;this instruction costs a lot
76     ;vmov.32        r1, d1[0]
77     ;mul            r0, r0, r0
78     ;str            r1, [r12]
79     ;sub            r0, r1, r0, asr #8
80
81     ;sum is in [-255x256, 255x256]. sumxsum is 32-bit. Shift to right should
82     ;have sign-bit exension, which is vshr.s. Have to use s32 to make it right.
83     vmull.s32       q5, d0, d0
84     vst1.32         {d1[0]}, [r12]              ;store sse
85     vshr.s32        d10, d10, #8
86     vsub.s32        d0, d1, d10
87
88     vmov.32         r0, d0[0]                   ;return
89     bx              lr
90
91     ENDP
92
93 ;================================
94 ;unsigned int vp8_variance16x8_c(
95 ;    unsigned char *src_ptr,
96 ;    int  source_stride,
97 ;    unsigned char *ref_ptr,
98 ;    int  recon_stride,
99 ;   unsigned int *sse)
100 |vp8_variance16x8_neon| PROC
101     vmov.i8         q8, #0                      ;q8 - sum
102     vmov.i8         q9, #0                      ;q9, q10 - sse
103     vmov.i8         q10, #0
104
105     mov             r12, #4
106
107 variance16x8_neon_loop
108     vld1.8          {q0}, [r0], r1              ;Load up source and reference
109     vld1.8          {q2}, [r2], r3
110     vld1.8          {q1}, [r0], r1
111     vld1.8          {q3}, [r2], r3
112
113     vsubl.u8        q11, d0, d4                 ;calculate diff
114     vsubl.u8        q12, d1, d5
115     vsubl.u8        q13, d2, d6
116     vsubl.u8        q14, d3, d7
117
118     vpadal.s16      q8, q11                     ;calculate sum
119     vmlal.s16       q9, d22, d22                ;calculate sse
120     vmlal.s16       q10, d23, d23
121
122     subs            r12, r12, #1
123
124     vpadal.s16      q8, q12
125     vmlal.s16       q9, d24, d24
126     vmlal.s16       q10, d25, d25
127     vpadal.s16      q8, q13
128     vmlal.s16       q9, d26, d26
129     vmlal.s16       q10, d27, d27
130     vpadal.s16      q8, q14
131     vmlal.s16       q9, d28, d28
132     vmlal.s16       q10, d29, d29
133
134     bne             variance16x8_neon_loop
135
136     vadd.u32        q10, q9, q10                ;accumulate sse
137     vpaddl.s32      q0, q8                      ;accumulate sum
138
139     ldr             r12, [sp]                   ;load *sse from stack
140
141     vpaddl.u32      q1, q10
142     vadd.s64        d0, d0, d1
143     vadd.u64        d1, d2, d3
144
145     vmull.s32       q5, d0, d0
146     vst1.32         {d1[0]}, [r12]              ;store sse
147     vshr.s32        d10, d10, #7
148     vsub.s32        d0, d1, d10
149
150     vmov.32         r0, d0[0]                   ;return
151     bx              lr
152
153     ENDP
154
155 ;=================================
156 ;unsigned int vp8_variance8x16_c(
157 ;    unsigned char *src_ptr,
158 ;    int  source_stride,
159 ;    unsigned char *ref_ptr,
160 ;    int  recon_stride,
161 ;   unsigned int *sse)
162
163 |vp8_variance8x16_neon| PROC
164     vmov.i8         q8, #0                      ;q8 - sum
165     vmov.i8         q9, #0                      ;q9, q10 - sse
166     vmov.i8         q10, #0
167
168     mov             r12, #8
169
170 variance8x16_neon_loop
171     vld1.8          {d0}, [r0], r1              ;Load up source and reference
172     vld1.8          {d4}, [r2], r3
173     vld1.8          {d2}, [r0], r1
174     vld1.8          {d6}, [r2], r3
175
176     vsubl.u8        q11, d0, d4                 ;calculate diff
177     vsubl.u8        q12, d2, d6
178
179     vpadal.s16      q8, q11                     ;calculate sum
180     vmlal.s16       q9, d22, d22                ;calculate sse
181     vmlal.s16       q10, d23, d23
182
183     subs            r12, r12, #1
184
185     vpadal.s16      q8, q12
186     vmlal.s16       q9, d24, d24
187     vmlal.s16       q10, d25, d25
188
189     bne             variance8x16_neon_loop
190
191     vadd.u32        q10, q9, q10                ;accumulate sse
192     vpaddl.s32      q0, q8                      ;accumulate sum
193
194     ldr             r12, [sp]                   ;load *sse from stack
195
196     vpaddl.u32      q1, q10
197     vadd.s64        d0, d0, d1
198     vadd.u64        d1, d2, d3
199
200     vmull.s32       q5, d0, d0
201     vst1.32         {d1[0]}, [r12]              ;store sse
202     vshr.s32        d10, d10, #7
203     vsub.s32        d0, d1, d10
204
205     vmov.32         r0, d0[0]                   ;return
206     bx              lr
207
208     ENDP
209
210 ;==================================
211 ; r0    unsigned char *src_ptr
212 ; r1    int source_stride
213 ; r2    unsigned char *ref_ptr
214 ; r3    int  recon_stride
215 ; stack unsigned int *sse
216 |vp8_variance8x8_neon| PROC
217     vmov.i8         q8, #0                      ;q8 - sum
218     vmov.i8         q9, #0                      ;q9, q10 - sse
219     vmov.i8         q10, #0
220
221     mov             r12, #2
222
223 variance8x8_neon_loop
224     vld1.8          {d0}, [r0], r1              ;Load up source and reference
225     vld1.8          {d4}, [r2], r3
226     vld1.8          {d1}, [r0], r1
227     vld1.8          {d5}, [r2], r3
228     vld1.8          {d2}, [r0], r1
229     vld1.8          {d6}, [r2], r3
230     vld1.8          {d3}, [r0], r1
231     vld1.8          {d7}, [r2], r3
232
233     vsubl.u8        q11, d0, d4                 ;calculate diff
234     vsubl.u8        q12, d1, d5
235     vsubl.u8        q13, d2, d6
236     vsubl.u8        q14, d3, d7
237
238     vpadal.s16      q8, q11                     ;calculate sum
239     vmlal.s16       q9, d22, d22                ;calculate sse
240     vmlal.s16       q10, d23, d23
241
242     subs            r12, r12, #1
243
244     vpadal.s16      q8, q12
245     vmlal.s16       q9, d24, d24
246     vmlal.s16       q10, d25, d25
247     vpadal.s16      q8, q13
248     vmlal.s16       q9, d26, d26
249     vmlal.s16       q10, d27, d27
250     vpadal.s16      q8, q14
251     vmlal.s16       q9, d28, d28
252     vmlal.s16       q10, d29, d29
253
254     bne             variance8x8_neon_loop
255
256     vadd.u32        q10, q9, q10                ;accumulate sse
257     vpaddl.s32      q0, q8                      ;accumulate sum
258
259     ldr             r12, [sp]                   ;load *sse from stack
260
261     vpaddl.u32      q1, q10
262     vadd.s64        d0, d0, d1
263     vadd.u64        d1, d2, d3
264
265     vmull.s32       q5, d0, d0
266     vst1.32         {d1[0]}, [r12]              ;store sse
267     vshr.s32        d10, d10, #6
268     vsub.s32        d0, d1, d10
269
270     vmov.32         r0, d0[0]                   ;return
271     bx              lr
272
273     ENDP
274
275     END