2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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.
12 EXPORT |vp8_variance_halfpixvar16x16_h_neon|
13 EXPORT |vp8_variance_halfpixvar16x16_v_neon|
14 EXPORT |vp8_variance_halfpixvar16x16_hv_neon|
15 EXPORT |vp8_sub_pixel_variance16x16s_neon|
20 AREA ||.text||, CODE, READONLY, ALIGN=2
22 ;================================================
23 ;unsigned int vp8_variance_halfpixvar16x16_h_neon
25 ; unsigned char *src_ptr, r0
26 ; int src_pixels_per_line, r1
27 ; unsigned char *dst_ptr, r2
28 ; int dst_pixels_per_line, r3
31 ;================================================
32 |vp8_variance_halfpixvar16x16_h_neon| PROC
36 mov r12, #4 ;loop counter
37 ldr lr, [sp, #68] ;load *sse from stack
38 vmov.i8 q8, #0 ;q8 - sum
39 vmov.i8 q9, #0 ;q9, q10 - sse
42 ;First Pass: output_height lines x output_width columns (16x16)
43 vp8_filt_fpo16x16s_4_0_loop_neon
44 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
45 vld1.8 {q11}, [r2], r3
46 vld1.u8 {d4, d5, d6, d7}, [r0], r1
47 vld1.8 {q12}, [r2], r3
48 vld1.u8 {d8, d9, d10, d11}, [r0], r1
49 vld1.8 {q13}, [r2], r3
50 vld1.u8 {d12, d13, d14, d15}, [r0], r1
56 vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
61 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
62 vld1.8 {q14}, [r2], r3
67 vsubl.u8 q4, d0, d22 ;diff
76 vpadal.s16 q8, q4 ;sum
77 vmlal.s16 q9, d8, d8 ;sse
83 vmlal.s16 q9, d10, d10
84 vmlal.s16 q10, d11, d11
86 vmlal.s16 q9, d12, d12
87 vmlal.s16 q10, d13, d13
89 vmlal.s16 q9, d14, d14
90 vmlal.s16 q10, d15, d15
92 vpadal.s16 q8, q0 ;sum
93 vmlal.s16 q9, d0, d0 ;sse
100 vmlal.s16 q10, d5, d5
103 vmlal.s16 q10, d7, d7
105 bne vp8_filt_fpo16x16s_4_0_loop_neon
107 vadd.u32 q10, q9, q10 ;accumulate sse
108 vpaddl.s32 q0, q8 ;accumulate sum
115 vst1.32 {d1[0]}, [lr] ;store sse
116 vshr.u32 d10, d10, #8
119 vmov.32 r0, d0[0] ;return
125 ;================================================
126 ;unsigned int vp8_variance_halfpixvar16x16_v_neon
128 ; unsigned char *src_ptr, r0
129 ; int src_pixels_per_line, r1
130 ; unsigned char *dst_ptr, r2
131 ; int dst_pixels_per_line, r3
134 ;================================================
135 |vp8_variance_halfpixvar16x16_v_neon| PROC
139 mov r12, #4 ;loop counter
141 vld1.u8 {q0}, [r0], r1 ;load src data
142 ldr lr, [sp, #68] ;load *sse from stack
144 vmov.i8 q8, #0 ;q8 - sum
145 vmov.i8 q9, #0 ;q9, q10 - sse
148 vp8_filt_spo16x16s_0_4_loop_neon
149 vld1.u8 {q2}, [r0], r1
150 vld1.8 {q1}, [r2], r3
151 vld1.u8 {q4}, [r0], r1
152 vld1.8 {q3}, [r2], r3
153 vld1.u8 {q6}, [r0], r1
154 vld1.8 {q5}, [r2], r3
155 vld1.u8 {q15}, [r0], r1
158 vld1.8 {q7}, [r2], r3
161 vrhadd.u8 q6, q6, q15
163 vsubl.u8 q11, d0, d2 ;diff
169 vsubl.u8 q2, d12, d14
170 vsubl.u8 q3, d13, d15
172 vpadal.s16 q8, q11 ;sum
173 vmlal.s16 q9, d22, d22 ;sse
174 vmlal.s16 q10, d23, d23
179 vmlal.s16 q9, d24, d24
180 vmlal.s16 q10, d25, d25
182 vmlal.s16 q9, d26, d26
183 vmlal.s16 q10, d27, d27
185 vmlal.s16 q9, d28, d28
186 vmlal.s16 q10, d29, d29
188 vpadal.s16 q8, q0 ;sum
189 vmlal.s16 q9, d0, d0 ;sse
190 vmlal.s16 q10, d1, d1
193 vmlal.s16 q10, d3, d3
196 vmlal.s16 q10, d5, d5
202 vmlal.s16 q10, d7, d7
204 bne vp8_filt_spo16x16s_0_4_loop_neon
206 vadd.u32 q10, q9, q10 ;accumulate sse
207 vpaddl.s32 q0, q8 ;accumulate sum
214 vst1.32 {d1[0]}, [lr] ;store sse
215 vshr.u32 d10, d10, #8
218 vmov.32 r0, d0[0] ;return
224 ;================================================
225 ;unsigned int vp8_variance_halfpixvar16x16_hv_neon
227 ; unsigned char *src_ptr, r0
228 ; int src_pixels_per_line, r1
229 ; unsigned char *dst_ptr, r2
230 ; int dst_pixels_per_line, r3
233 ;================================================
234 |vp8_variance_halfpixvar16x16_hv_neon| PROC
238 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
240 ldr lr, [sp, #68] ;load *sse from stack
241 vmov.i8 q13, #0 ;q8 - sum
242 vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
244 vmov.i8 q14, #0 ;q9, q10 - sse
247 mov r12, #4 ;loop counter
248 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
250 ;First Pass: output_height lines x output_width columns (17x16)
251 vp8_filt16x16s_4_4_loop_neon
252 vld1.u8 {d4, d5, d6, d7}, [r0], r1
253 vld1.u8 {d8, d9, d10, d11}, [r0], r1
254 vld1.u8 {d12, d13, d14, d15}, [r0], r1
255 vld1.u8 {d16, d17, d18, d19}, [r0], r1
259 ;pld [r0, r1, lsl #1]
261 vext.8 q3, q2, q3, #1 ;construct src_ptr[1]
262 vext.8 q5, q4, q5, #1
263 vext.8 q7, q6, q7, #1
264 vext.8 q9, q8, q9, #1
266 vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
271 vld1.8 {q5}, [r2], r3
273 vld1.8 {q6}, [r2], r3
275 vld1.8 {q7}, [r2], r3
277 vld1.8 {q8}, [r2], r3
280 vsubl.u8 q9, d0, d10 ;diff
281 vsubl.u8 q10, d1, d11
282 vsubl.u8 q11, d2, d12
283 vsubl.u8 q12, d3, d13
285 vsubl.u8 q0, d4, d14 ;diff
290 vpadal.s16 q13, q9 ;sum
291 vmlal.s16 q14, d18, d18 ;sse
292 vmlal.s16 q15, d19, d19
294 vpadal.s16 q13, q10 ;sum
295 vmlal.s16 q14, d20, d20 ;sse
296 vmlal.s16 q15, d21, d21
298 vpadal.s16 q13, q11 ;sum
299 vmlal.s16 q14, d22, d22 ;sse
300 vmlal.s16 q15, d23, d23
302 vpadal.s16 q13, q12 ;sum
303 vmlal.s16 q14, d24, d24 ;sse
304 vmlal.s16 q15, d25, d25
308 vpadal.s16 q13, q0 ;sum
309 vmlal.s16 q14, d0, d0 ;sse
310 vmlal.s16 q15, d1, d1
312 vpadal.s16 q13, q1 ;sum
313 vmlal.s16 q14, d2, d2 ;sse
314 vmlal.s16 q15, d3, d3
316 vpadal.s16 q13, q5 ;sum
317 vmlal.s16 q14, d10, d10 ;sse
318 vmlal.s16 q15, d11, d11
322 vpadal.s16 q13, q6 ;sum
323 vmlal.s16 q14, d12, d12 ;sse
324 vmlal.s16 q15, d13, d13
326 bne vp8_filt16x16s_4_4_loop_neon
328 vadd.u32 q15, q14, q15 ;accumulate sse
329 vpaddl.s32 q0, q13 ;accumulate sum
336 vst1.32 {d1[0]}, [lr] ;store sse
337 vshr.u32 d10, d10, #8
340 vmov.32 r0, d0[0] ;return
346 ;==============================
347 ; r0 unsigned char *src_ptr,
348 ; r1 int src_pixels_per_line,
351 ; stack unsigned char *dst_ptr,
352 ; stack int dst_pixels_per_line,
353 ; stack unsigned int *sse
354 ;note: in vp8_find_best_half_pixel_step()(called when 8<Speed<15), and first call of vp8_find_best_sub_pixel_step()
355 ;(called when speed<=8). xoffset/yoffset can only be 4 or 0, which means either by pass the filter,
356 ;or filter coeff is {64, 64}. This simplified program only works in this situation.
357 ;note: It happens that both xoffset and yoffset are zero. This can be handled in c code later.
359 |vp8_sub_pixel_variance16x16s_neon| PROC
363 ldr r4, [sp, #72] ;load *dst_ptr from stack
364 ldr r12, [sp, #76] ;load dst_pixels_per_line from stack
365 ldr lr, [sp, #80] ;load *sse from stack
367 cmp r2, #0 ;skip first_pass filter if xoffset=0
368 beq secondpass_bfilter16x16s_only
370 cmp r3, #0 ;skip second_pass filter if yoffset=0
371 beq firstpass_bfilter16x16s_only
373 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
374 sub sp, sp, #256 ;reserve space on stack for temporary storage
375 vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
377 mov r2, #4 ;loop counter
378 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
380 ;First Pass: output_height lines x output_width columns (17x16)
381 vp8e_filt_blk2d_fp16x16s_loop_neon
382 vld1.u8 {d4, d5, d6, d7}, [r0], r1
383 vld1.u8 {d8, d9, d10, d11}, [r0], r1
384 vld1.u8 {d12, d13, d14, d15}, [r0], r1
385 vld1.u8 {d16, d17, d18, d19}, [r0], r1
389 ;pld [r0, r1, lsl #1]
391 vext.8 q3, q2, q3, #1 ;construct src_ptr[1]
392 vext.8 q5, q4, q5, #1
393 vext.8 q7, q6, q7, #1
394 vext.8 q9, q8, q9, #1
396 vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
407 vst1.u8 {d0, d1 ,d2, d3}, [r3]! ;store result
409 vst1.u8 {d4, d5, d6, d7}, [r3]!
411 bne vp8e_filt_blk2d_fp16x16s_loop_neon
413 b sub_pixel_variance16x16s_neon
415 ;--------------------
416 firstpass_bfilter16x16s_only
417 mov r2, #2 ;loop counter
418 sub sp, sp, #256 ;reserve space on stack for temporary storage
421 ;First Pass: output_height lines x output_width columns (16x16)
422 vp8e_filt_blk2d_fpo16x16s_loop_neon
423 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
424 vld1.u8 {d4, d5, d6, d7}, [r0], r1
425 vld1.u8 {d8, d9, d10, d11}, [r0], r1
426 vld1.u8 {d12, d13, d14, d15}, [r0], r1
430 ;pld [r0, r1, lsl #1]
432 vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
433 vld1.u8 {d16, d17, d18, d19}, [r0], r1
434 vext.8 q3, q2, q3, #1
435 vld1.u8 {d20, d21, d22, d23}, [r0], r1
436 vext.8 q5, q4, q5, #1
437 vld1.u8 {d24, d25, d26, d27}, [r0], r1
438 vext.8 q7, q6, q7, #1
439 vld1.u8 {d28, d29, d30, d31}, [r0], r1
440 vext.8 q9, q8, q9, #1
441 vext.8 q11, q10, q11, #1
442 vext.8 q13, q12, q13, #1
443 vext.8 q15, q14, q15, #1
445 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
450 vrhadd.u8 q5, q10, q11
451 vrhadd.u8 q6, q12, q13
452 vrhadd.u8 q7, q14, q15
456 vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result
457 vst1.u8 {d4, d5, d6, d7}, [r3]!
458 vst1.u8 {d8, d9, d10, d11}, [r3]!
459 vst1.u8 {d12, d13, d14, d15}, [r3]!
461 bne vp8e_filt_blk2d_fpo16x16s_loop_neon
463 b sub_pixel_variance16x16s_neon
465 ;---------------------
466 secondpass_bfilter16x16s_only
467 sub sp, sp, #256 ;reserve space on stack for temporary storage
469 mov r2, #2 ;loop counter
470 vld1.u8 {d0, d1}, [r0], r1 ;load src data
473 vp8e_filt_blk2d_spo16x16s_loop_neon
474 vld1.u8 {d2, d3}, [r0], r1
475 vld1.u8 {d4, d5}, [r0], r1
476 vld1.u8 {d6, d7}, [r0], r1
477 vld1.u8 {d8, d9}, [r0], r1
480 vld1.u8 {d10, d11}, [r0], r1
482 vld1.u8 {d12, d13}, [r0], r1
484 vld1.u8 {d14, d15}, [r0], r1
486 vld1.u8 {d16, d17}, [r0], r1
494 vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result
496 vst1.u8 {d4, d5, d6, d7}, [r3]!
497 vst1.u8 {d8, d9, d10, d11}, [r3]! ;store result
498 vst1.u8 {d12, d13, d14, d15}, [r3]!
500 bne vp8e_filt_blk2d_spo16x16s_loop_neon
502 b sub_pixel_variance16x16s_neon
504 ;----------------------------
506 sub_pixel_variance16x16s_neon
507 vmov.i8 q8, #0 ;q8 - sum
508 vmov.i8 q9, #0 ;q9, q10 - sse
514 sub_pixel_variance16x16s_neon_loop
515 vld1.8 {q0}, [r3]! ;Load up source and reference
516 vld1.8 {q1}, [r4], r12
518 vld1.8 {q3}, [r4], r12
520 vld1.8 {q5}, [r4], r12
522 vld1.8 {q7}, [r4], r12
524 vsubl.u8 q11, d0, d2 ;diff
530 vsubl.u8 q2, d12, d14
531 vsubl.u8 q3, d13, d15
533 vpadal.s16 q8, q11 ;sum
534 vmlal.s16 q9, d22, d22 ;sse
535 vmlal.s16 q10, d23, d23
540 vmlal.s16 q9, d24, d24
541 vmlal.s16 q10, d25, d25
543 vmlal.s16 q9, d26, d26
544 vmlal.s16 q10, d27, d27
546 vmlal.s16 q9, d28, d28
547 vmlal.s16 q10, d29, d29
549 vpadal.s16 q8, q0 ;sum
550 vmlal.s16 q9, d0, d0 ;sse
551 vmlal.s16 q10, d1, d1
554 vmlal.s16 q10, d3, d3
557 vmlal.s16 q10, d5, d5
560 vmlal.s16 q10, d7, d7
562 bne sub_pixel_variance16x16s_neon_loop
564 vadd.u32 q10, q9, q10 ;accumulate sse
565 vpaddl.s32 q0, q8 ;accumulate sum
572 vst1.32 {d1[0]}, [lr] ;store sse
573 vshr.u32 d10, d10, #8
577 vmov.32 r0, d0[0] ;return