OLD | NEW |
| (Empty) |
1 ; | |
2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. | |
3 ; | |
4 ; Use of this source code is governed by a BSD-style license | |
5 ; that can be found in the LICENSE file in the root of the source | |
6 ; tree. An additional intellectual property rights grant can be found | |
7 ; in the file PATENTS. All contributing project authors may | |
8 ; be found in the AUTHORS file in the root of the source tree. | |
9 ; | |
10 | |
11 | |
12 ;----------------- | |
13 | |
14 EXPORT |vp8_sub_pixel_variance16x16_neon_func| | |
15 ARM | |
16 REQUIRE8 | |
17 PRESERVE8 | |
18 | |
19 AREA ||.text||, CODE, READONLY, ALIGN=2 | |
20 ; r0 unsigned char *src_ptr, | |
21 ; r1 int src_pixels_per_line, | |
22 ; r2 int xoffset, | |
23 ; r3 int yoffset, | |
24 ; stack(r4) unsigned char *dst_ptr, | |
25 ; stack(r5) int dst_pixels_per_line, | |
26 ; stack(r6) unsigned int *sse | |
27 ;note: most of the code is copied from bilinear_predict16x16_neon and vp8_varian
ce16x16_neon. | |
28 | |
29 bilinear_taps_coeff | |
30 DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112 | |
31 | |
32 |vp8_sub_pixel_variance16x16_neon_func| PROC | |
33 push {r4-r6, lr} | |
34 vpush {d8-d15} | |
35 | |
36 adr r12, bilinear_taps_coeff | |
37 ldr r4, [sp, #80] ;load *dst_ptr from stack | |
38 ldr r5, [sp, #84] ;load dst_pixels_per_line from stack | |
39 ldr r6, [sp, #88] ;load *sse from stack | |
40 | |
41 cmp r2, #0 ;skip first_pass filter if xoffset=0 | |
42 beq secondpass_bfilter16x16_only | |
43 | |
44 add r2, r12, r2, lsl #3 ;calculate filter location | |
45 | |
46 cmp r3, #0 ;skip second_pass filter if yoffset=
0 | |
47 | |
48 vld1.s32 {d31}, [r2] ;load first_pass filter | |
49 | |
50 beq firstpass_bfilter16x16_only | |
51 | |
52 sub sp, sp, #272 ;reserve space on stack for temporar
y storage | |
53 vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data | |
54 mov lr, sp | |
55 vld1.u8 {d5, d6, d7}, [r0], r1 | |
56 | |
57 mov r2, #3 ;loop counter | |
58 vld1.u8 {d8, d9, d10}, [r0], r1 | |
59 | |
60 vdup.8 d0, d31[0] ;first_pass filter (d0 d1) | |
61 vld1.u8 {d11, d12, d13}, [r0], r1 | |
62 | |
63 vdup.8 d1, d31[4] | |
64 | |
65 ;First Pass: output_height lines x output_width columns (17x16) | |
66 vp8e_filt_blk2d_fp16x16_loop_neon | |
67 pld [r0] | |
68 pld [r0, r1] | |
69 pld [r0, r1, lsl #1] | |
70 | |
71 vmull.u8 q7, d2, d0 ;(src_ptr[0] * Filter[0]) | |
72 vmull.u8 q8, d3, d0 | |
73 vmull.u8 q9, d5, d0 | |
74 vmull.u8 q10, d6, d0 | |
75 vmull.u8 q11, d8, d0 | |
76 vmull.u8 q12, d9, d0 | |
77 vmull.u8 q13, d11, d0 | |
78 vmull.u8 q14, d12, d0 | |
79 | |
80 vext.8 d2, d2, d3, #1 ;construct src_ptr[1] | |
81 vext.8 d5, d5, d6, #1 | |
82 vext.8 d8, d8, d9, #1 | |
83 vext.8 d11, d11, d12, #1 | |
84 | |
85 vmlal.u8 q7, d2, d1 ;(src_ptr[0] * Filter[1]) | |
86 vmlal.u8 q9, d5, d1 | |
87 vmlal.u8 q11, d8, d1 | |
88 vmlal.u8 q13, d11, d1 | |
89 | |
90 vext.8 d3, d3, d4, #1 | |
91 vext.8 d6, d6, d7, #1 | |
92 vext.8 d9, d9, d10, #1 | |
93 vext.8 d12, d12, d13, #1 | |
94 | |
95 vmlal.u8 q8, d3, d1 ;(src_ptr[0] * Filter[1]) | |
96 vmlal.u8 q10, d6, d1 | |
97 vmlal.u8 q12, d9, d1 | |
98 vmlal.u8 q14, d12, d1 | |
99 | |
100 subs r2, r2, #1 | |
101 | |
102 vqrshrn.u16 d14, q7, #7 ;shift/round/saturate to u8 | |
103 vqrshrn.u16 d15, q8, #7 | |
104 vqrshrn.u16 d16, q9, #7 | |
105 vqrshrn.u16 d17, q10, #7 | |
106 vqrshrn.u16 d18, q11, #7 | |
107 vqrshrn.u16 d19, q12, #7 | |
108 vqrshrn.u16 d20, q13, #7 | |
109 | |
110 vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data | |
111 vqrshrn.u16 d21, q14, #7 | |
112 vld1.u8 {d5, d6, d7}, [r0], r1 | |
113 | |
114 vst1.u8 {d14, d15, d16, d17}, [lr]! ;store result | |
115 vld1.u8 {d8, d9, d10}, [r0], r1 | |
116 vst1.u8 {d18, d19, d20, d21}, [lr]! | |
117 vld1.u8 {d11, d12, d13}, [r0], r1 | |
118 | |
119 bne vp8e_filt_blk2d_fp16x16_loop_neon | |
120 | |
121 ;First-pass filtering for rest 5 lines | |
122 vld1.u8 {d14, d15, d16}, [r0], r1 | |
123 | |
124 vmull.u8 q9, d2, d0 ;(src_ptr[0] * Filter[0]) | |
125 vmull.u8 q10, d3, d0 | |
126 vmull.u8 q11, d5, d0 | |
127 vmull.u8 q12, d6, d0 | |
128 vmull.u8 q13, d8, d0 | |
129 vmull.u8 q14, d9, d0 | |
130 | |
131 vext.8 d2, d2, d3, #1 ;construct src_ptr[1] | |
132 vext.8 d5, d5, d6, #1 | |
133 vext.8 d8, d8, d9, #1 | |
134 | |
135 vmlal.u8 q9, d2, d1 ;(src_ptr[0] * Filter[1]) | |
136 vmlal.u8 q11, d5, d1 | |
137 vmlal.u8 q13, d8, d1 | |
138 | |
139 vext.8 d3, d3, d4, #1 | |
140 vext.8 d6, d6, d7, #1 | |
141 vext.8 d9, d9, d10, #1 | |
142 | |
143 vmlal.u8 q10, d3, d1 ;(src_ptr[0] * Filter[1]) | |
144 vmlal.u8 q12, d6, d1 | |
145 vmlal.u8 q14, d9, d1 | |
146 | |
147 vmull.u8 q1, d11, d0 | |
148 vmull.u8 q2, d12, d0 | |
149 vmull.u8 q3, d14, d0 | |
150 vmull.u8 q4, d15, d0 | |
151 | |
152 vext.8 d11, d11, d12, #1 ;construct src_ptr[1] | |
153 vext.8 d14, d14, d15, #1 | |
154 | |
155 vmlal.u8 q1, d11, d1 ;(src_ptr[0] * Filter[1]) | |
156 vmlal.u8 q3, d14, d1 | |
157 | |
158 vext.8 d12, d12, d13, #1 | |
159 vext.8 d15, d15, d16, #1 | |
160 | |
161 vmlal.u8 q2, d12, d1 ;(src_ptr[0] * Filter[1]) | |
162 vmlal.u8 q4, d15, d1 | |
163 | |
164 vqrshrn.u16 d10, q9, #7 ;shift/round/saturate to u8 | |
165 vqrshrn.u16 d11, q10, #7 | |
166 vqrshrn.u16 d12, q11, #7 | |
167 vqrshrn.u16 d13, q12, #7 | |
168 vqrshrn.u16 d14, q13, #7 | |
169 vqrshrn.u16 d15, q14, #7 | |
170 vqrshrn.u16 d16, q1, #7 | |
171 vqrshrn.u16 d17, q2, #7 | |
172 vqrshrn.u16 d18, q3, #7 | |
173 vqrshrn.u16 d19, q4, #7 | |
174 | |
175 vst1.u8 {d10, d11, d12, d13}, [lr]! ;store result | |
176 vst1.u8 {d14, d15, d16, d17}, [lr]! | |
177 vst1.u8 {d18, d19}, [lr]! | |
178 | |
179 ;Second pass: 16x16 | |
180 ;secondpass_filter | |
181 add r3, r12, r3, lsl #3 | |
182 sub lr, lr, #272 | |
183 | |
184 vld1.u32 {d31}, [r3] ;load second_pass filter | |
185 | |
186 sub sp, sp, #256 | |
187 mov r3, sp | |
188 | |
189 vld1.u8 {d22, d23}, [lr]! ;load src data | |
190 | |
191 vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d
1) | |
192 vdup.8 d1, d31[4] | |
193 mov r12, #4 ;loop counter | |
194 | |
195 vp8e_filt_blk2d_sp16x16_loop_neon | |
196 vld1.u8 {d24, d25}, [lr]! | |
197 vmull.u8 q1, d22, d0 ;(src_ptr[0] * Filter[0]) | |
198 vld1.u8 {d26, d27}, [lr]! | |
199 vmull.u8 q2, d23, d0 | |
200 vld1.u8 {d28, d29}, [lr]! | |
201 vmull.u8 q3, d24, d0 | |
202 vld1.u8 {d30, d31}, [lr]! | |
203 | |
204 vmull.u8 q4, d25, d0 | |
205 vmull.u8 q5, d26, d0 | |
206 vmull.u8 q6, d27, d0 | |
207 vmull.u8 q7, d28, d0 | |
208 vmull.u8 q8, d29, d0 | |
209 | |
210 vmlal.u8 q1, d24, d1 ;(src_ptr[pixel_step] * Filter[1]) | |
211 vmlal.u8 q2, d25, d1 | |
212 vmlal.u8 q3, d26, d1 | |
213 vmlal.u8 q4, d27, d1 | |
214 vmlal.u8 q5, d28, d1 | |
215 vmlal.u8 q6, d29, d1 | |
216 vmlal.u8 q7, d30, d1 | |
217 vmlal.u8 q8, d31, d1 | |
218 | |
219 subs r12, r12, #1 | |
220 | |
221 vqrshrn.u16 d2, q1, #7 ;shift/round/saturate to u8 | |
222 vqrshrn.u16 d3, q2, #7 | |
223 vqrshrn.u16 d4, q3, #7 | |
224 vqrshrn.u16 d5, q4, #7 | |
225 vqrshrn.u16 d6, q5, #7 | |
226 vqrshrn.u16 d7, q6, #7 | |
227 vqrshrn.u16 d8, q7, #7 | |
228 vqrshrn.u16 d9, q8, #7 | |
229 | |
230 vst1.u8 {d2, d3}, [r3]! ;store result | |
231 vst1.u8 {d4, d5}, [r3]! | |
232 vst1.u8 {d6, d7}, [r3]! | |
233 vmov q11, q15 | |
234 vst1.u8 {d8, d9}, [r3]! | |
235 | |
236 bne vp8e_filt_blk2d_sp16x16_loop_neon | |
237 | |
238 b sub_pixel_variance16x16_neon | |
239 | |
240 ;-------------------- | |
241 firstpass_bfilter16x16_only | |
242 mov r2, #4 ;loop counter | |
243 sub sp, sp, #528 ;reserve space on stack for temporar
y storage | |
244 vdup.8 d0, d31[0] ;first_pass filter (d0 d1) | |
245 vdup.8 d1, d31[4] | |
246 mov r3, sp | |
247 | |
248 ;First Pass: output_height lines x output_width columns (16x16) | |
249 vp8e_filt_blk2d_fpo16x16_loop_neon | |
250 vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data | |
251 vld1.u8 {d5, d6, d7}, [r0], r1 | |
252 vld1.u8 {d8, d9, d10}, [r0], r1 | |
253 vld1.u8 {d11, d12, d13}, [r0], r1 | |
254 | |
255 pld [r0] | |
256 pld [r0, r1] | |
257 pld [r0, r1, lsl #1] | |
258 | |
259 vmull.u8 q7, d2, d0 ;(src_ptr[0] * Filter[0]) | |
260 vmull.u8 q8, d3, d0 | |
261 vmull.u8 q9, d5, d0 | |
262 vmull.u8 q10, d6, d0 | |
263 vmull.u8 q11, d8, d0 | |
264 vmull.u8 q12, d9, d0 | |
265 vmull.u8 q13, d11, d0 | |
266 vmull.u8 q14, d12, d0 | |
267 | |
268 vext.8 d2, d2, d3, #1 ;construct src_ptr[1] | |
269 vext.8 d5, d5, d6, #1 | |
270 vext.8 d8, d8, d9, #1 | |
271 vext.8 d11, d11, d12, #1 | |
272 | |
273 vmlal.u8 q7, d2, d1 ;(src_ptr[0] * Filter[1]) | |
274 vmlal.u8 q9, d5, d1 | |
275 vmlal.u8 q11, d8, d1 | |
276 vmlal.u8 q13, d11, d1 | |
277 | |
278 vext.8 d3, d3, d4, #1 | |
279 vext.8 d6, d6, d7, #1 | |
280 vext.8 d9, d9, d10, #1 | |
281 vext.8 d12, d12, d13, #1 | |
282 | |
283 vmlal.u8 q8, d3, d1 ;(src_ptr[0] * Filter[1]) | |
284 vmlal.u8 q10, d6, d1 | |
285 vmlal.u8 q12, d9, d1 | |
286 vmlal.u8 q14, d12, d1 | |
287 | |
288 subs r2, r2, #1 | |
289 | |
290 vqrshrn.u16 d14, q7, #7 ;shift/round/saturate to u8 | |
291 vqrshrn.u16 d15, q8, #7 | |
292 vqrshrn.u16 d16, q9, #7 | |
293 vqrshrn.u16 d17, q10, #7 | |
294 vqrshrn.u16 d18, q11, #7 | |
295 vqrshrn.u16 d19, q12, #7 | |
296 vqrshrn.u16 d20, q13, #7 | |
297 vst1.u8 {d14, d15}, [r3]! ;store result | |
298 vqrshrn.u16 d21, q14, #7 | |
299 | |
300 vst1.u8 {d16, d17}, [r3]! | |
301 vst1.u8 {d18, d19}, [r3]! | |
302 vst1.u8 {d20, d21}, [r3]! | |
303 | |
304 bne vp8e_filt_blk2d_fpo16x16_loop_neon | |
305 | |
306 b sub_pixel_variance16x16_neon | |
307 | |
308 ;--------------------- | |
309 secondpass_bfilter16x16_only | |
310 ;Second pass: 16x16 | |
311 ;secondpass_filter | |
312 sub sp, sp, #528 ;reserve space on stack for temporar
y storage | |
313 add r3, r12, r3, lsl #3 | |
314 mov r12, #4 ;loop counter | |
315 vld1.u32 {d31}, [r3] ;load second_pass filter | |
316 vld1.u8 {d22, d23}, [r0], r1 ;load src data | |
317 mov r3, sp | |
318 | |
319 vdup.8 d0, d31[0] ;second_pass filter parameters (
d0 d1) | |
320 vdup.8 d1, d31[4] | |
321 | |
322 vp8e_filt_blk2d_spo16x16_loop_neon | |
323 vld1.u8 {d24, d25}, [r0], r1 | |
324 vmull.u8 q1, d22, d0 ;(src_ptr[0] * Filter[0]) | |
325 vld1.u8 {d26, d27}, [r0], r1 | |
326 vmull.u8 q2, d23, d0 | |
327 vld1.u8 {d28, d29}, [r0], r1 | |
328 vmull.u8 q3, d24, d0 | |
329 vld1.u8 {d30, d31}, [r0], r1 | |
330 | |
331 vmull.u8 q4, d25, d0 | |
332 vmull.u8 q5, d26, d0 | |
333 vmull.u8 q6, d27, d0 | |
334 vmull.u8 q7, d28, d0 | |
335 vmull.u8 q8, d29, d0 | |
336 | |
337 vmlal.u8 q1, d24, d1 ;(src_ptr[pixel_step] * Filter[1]) | |
338 vmlal.u8 q2, d25, d1 | |
339 vmlal.u8 q3, d26, d1 | |
340 vmlal.u8 q4, d27, d1 | |
341 vmlal.u8 q5, d28, d1 | |
342 vmlal.u8 q6, d29, d1 | |
343 vmlal.u8 q7, d30, d1 | |
344 vmlal.u8 q8, d31, d1 | |
345 | |
346 vqrshrn.u16 d2, q1, #7 ;shift/round/saturate to u8 | |
347 vqrshrn.u16 d3, q2, #7 | |
348 vqrshrn.u16 d4, q3, #7 | |
349 vqrshrn.u16 d5, q4, #7 | |
350 vqrshrn.u16 d6, q5, #7 | |
351 vqrshrn.u16 d7, q6, #7 | |
352 vqrshrn.u16 d8, q7, #7 | |
353 vqrshrn.u16 d9, q8, #7 | |
354 | |
355 vst1.u8 {d2, d3}, [r3]! ;store result | |
356 subs r12, r12, #1 | |
357 vst1.u8 {d4, d5}, [r3]! | |
358 vmov q11, q15 | |
359 vst1.u8 {d6, d7}, [r3]! | |
360 vst1.u8 {d8, d9}, [r3]! | |
361 | |
362 bne vp8e_filt_blk2d_spo16x16_loop_neon | |
363 | |
364 b sub_pixel_variance16x16_neon | |
365 | |
366 ;---------------------------- | |
367 ;variance16x16 | |
368 sub_pixel_variance16x16_neon | |
369 vmov.i8 q8, #0 ;q8 - sum | |
370 vmov.i8 q9, #0 ;q9, q10 - sse | |
371 vmov.i8 q10, #0 | |
372 | |
373 sub r3, r3, #256 | |
374 mov r12, #8 | |
375 | |
376 sub_pixel_variance16x16_neon_loop | |
377 vld1.8 {q0}, [r3]! ;Load up source and reference | |
378 vld1.8 {q2}, [r4], r5 | |
379 vld1.8 {q1}, [r3]! | |
380 vld1.8 {q3}, [r4], r5 | |
381 | |
382 vsubl.u8 q11, d0, d4 ;diff | |
383 vsubl.u8 q12, d1, d5 | |
384 vsubl.u8 q13, d2, d6 | |
385 vsubl.u8 q14, d3, d7 | |
386 | |
387 vpadal.s16 q8, q11 ;sum | |
388 vmlal.s16 q9, d22, d22 ;sse | |
389 vmlal.s16 q10, d23, d23 | |
390 | |
391 subs r12, r12, #1 | |
392 | |
393 vpadal.s16 q8, q12 | |
394 vmlal.s16 q9, d24, d24 | |
395 vmlal.s16 q10, d25, d25 | |
396 vpadal.s16 q8, q13 | |
397 vmlal.s16 q9, d26, d26 | |
398 vmlal.s16 q10, d27, d27 | |
399 vpadal.s16 q8, q14 | |
400 vmlal.s16 q9, d28, d28 | |
401 vmlal.s16 q10, d29, d29 | |
402 | |
403 bne sub_pixel_variance16x16_neon_loop | |
404 | |
405 vadd.u32 q10, q9, q10 ;accumulate sse | |
406 vpaddl.s32 q0, q8 ;accumulate sum | |
407 | |
408 vpaddl.u32 q1, q10 | |
409 vadd.s64 d0, d0, d1 | |
410 vadd.u64 d1, d2, d3 | |
411 | |
412 vmull.s32 q5, d0, d0 | |
413 vst1.32 {d1[0]}, [r6] ;store sse | |
414 vshr.u32 d10, d10, #8 | |
415 vsub.u32 d0, d1, d10 | |
416 | |
417 add sp, sp, #528 | |
418 vmov.32 r0, d0[0] ;return | |
419 | |
420 vpop {d8-d15} | |
421 pop {r4-r6,pc} | |
422 | |
423 ENDP | |
424 | |
425 END | |
OLD | NEW |