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
35 mov r12, #4 ;loop counter
36 ldr lr, [sp, #4] ;load *sse from stack
37 vmov.i8 q8, #0 ;q8 - sum
38 vmov.i8 q9, #0 ;q9, q10 - sse
41 ;First Pass: output_height lines x output_width columns (16x16)
42 vp8_filt_fpo16x16s_4_0_loop_neon
43 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
44 vld1.8 {q11}, [r2], r3
45 vld1.u8 {d4, d5, d6, d7}, [r0], r1
46 vld1.8 {q12}, [r2], r3
47 vld1.u8 {d8, d9, d10, d11}, [r0], r1
48 vld1.8 {q13}, [r2], r3
49 vld1.u8 {d12, d13, d14, d15}, [r0], r1
55 vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
60 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
61 vld1.8 {q14}, [r2], r3
66 vsubl.u8 q4, d0, d22 ;diff
75 vpadal.s16 q8, q4 ;sum
76 vmlal.s16 q9, d8, d8 ;sse
82 vmlal.s16 q9, d10, d10
83 vmlal.s16 q10, d11, d11
85 vmlal.s16 q9, d12, d12
86 vmlal.s16 q10, d13, d13
88 vmlal.s16 q9, d14, d14
89 vmlal.s16 q10, d15, d15
91 vpadal.s16 q8, q0 ;sum
92 vmlal.s16 q9, d0, d0 ;sse
102 vmlal.s16 q10, d7, d7
104 bne vp8_filt_fpo16x16s_4_0_loop_neon
106 vadd.u32 q10, q9, q10 ;accumulate sse
107 vpaddl.s32 q0, q8 ;accumulate sum
114 vst1.32 {d1[0]}, [lr] ;store sse
115 vshr.u32 d10, d10, #8
118 vmov.32 r0, d0[0] ;return
122 ;================================================
123 ;unsigned int vp8_variance_halfpixvar16x16_v_neon
125 ; unsigned char *src_ptr, r0
126 ; int src_pixels_per_line, r1
127 ; unsigned char *dst_ptr, r2
128 ; int dst_pixels_per_line, r3
131 ;================================================
132 |vp8_variance_halfpixvar16x16_v_neon| PROC
135 mov r12, #4 ;loop counter
137 vld1.u8 {q0}, [r0], r1 ;load src data
138 ldr lr, [sp, #4] ;load *sse from stack
140 vmov.i8 q8, #0 ;q8 - sum
141 vmov.i8 q9, #0 ;q9, q10 - sse
144 vp8_filt_spo16x16s_0_4_loop_neon
145 vld1.u8 {q2}, [r0], r1
146 vld1.8 {q1}, [r2], r3
147 vld1.u8 {q4}, [r0], r1
148 vld1.8 {q3}, [r2], r3
149 vld1.u8 {q6}, [r0], r1
150 vld1.8 {q5}, [r2], r3
151 vld1.u8 {q15}, [r0], r1
154 vld1.8 {q7}, [r2], r3
157 vrhadd.u8 q6, q6, q15
159 vsubl.u8 q11, d0, d2 ;diff
165 vsubl.u8 q2, d12, d14
166 vsubl.u8 q3, d13, d15
168 vpadal.s16 q8, q11 ;sum
169 vmlal.s16 q9, d22, d22 ;sse
170 vmlal.s16 q10, d23, d23
175 vmlal.s16 q9, d24, d24
176 vmlal.s16 q10, d25, d25
178 vmlal.s16 q9, d26, d26
179 vmlal.s16 q10, d27, d27
181 vmlal.s16 q9, d28, d28
182 vmlal.s16 q10, d29, d29
184 vpadal.s16 q8, q0 ;sum
185 vmlal.s16 q9, d0, d0 ;sse
186 vmlal.s16 q10, d1, d1
189 vmlal.s16 q10, d3, d3
192 vmlal.s16 q10, d5, d5
198 vmlal.s16 q10, d7, d7
200 bne vp8_filt_spo16x16s_0_4_loop_neon
202 vadd.u32 q10, q9, q10 ;accumulate sse
203 vpaddl.s32 q0, q8 ;accumulate sum
210 vst1.32 {d1[0]}, [lr] ;store sse
211 vshr.u32 d10, d10, #8
214 vmov.32 r0, d0[0] ;return
218 ;================================================
219 ;unsigned int vp8_variance_halfpixvar16x16_hv_neon
221 ; unsigned char *src_ptr, r0
222 ; int src_pixels_per_line, r1
223 ; unsigned char *dst_ptr, r2
224 ; int dst_pixels_per_line, r3
227 ;================================================
228 |vp8_variance_halfpixvar16x16_hv_neon| PROC
231 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
233 ldr lr, [sp, #4] ;load *sse from stack
234 vmov.i8 q13, #0 ;q8 - sum
235 vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
237 vmov.i8 q14, #0 ;q9, q10 - sse
240 mov r12, #4 ;loop counter
241 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
243 ;First Pass: output_height lines x output_width columns (17x16)
244 vp8_filt16x16s_4_4_loop_neon
245 vld1.u8 {d4, d5, d6, d7}, [r0], r1
246 vld1.u8 {d8, d9, d10, d11}, [r0], r1
247 vld1.u8 {d12, d13, d14, d15}, [r0], r1
248 vld1.u8 {d16, d17, d18, d19}, [r0], r1
252 ;pld [r0, r1, lsl #1]
254 vext.8 q3, q2, q3, #1 ;construct src_ptr[1]
255 vext.8 q5, q4, q5, #1
256 vext.8 q7, q6, q7, #1
257 vext.8 q9, q8, q9, #1
259 vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
264 vld1.8 {q5}, [r2], r3
266 vld1.8 {q6}, [r2], r3
268 vld1.8 {q7}, [r2], r3
270 vld1.8 {q8}, [r2], r3
273 vsubl.u8 q9, d0, d10 ;diff
274 vsubl.u8 q10, d1, d11
275 vsubl.u8 q11, d2, d12
276 vsubl.u8 q12, d3, d13
278 vsubl.u8 q0, d4, d14 ;diff
283 vpadal.s16 q13, q9 ;sum
284 vmlal.s16 q14, d18, d18 ;sse
285 vmlal.s16 q15, d19, d19
287 vpadal.s16 q13, q10 ;sum
288 vmlal.s16 q14, d20, d20 ;sse
289 vmlal.s16 q15, d21, d21
291 vpadal.s16 q13, q11 ;sum
292 vmlal.s16 q14, d22, d22 ;sse
293 vmlal.s16 q15, d23, d23
295 vpadal.s16 q13, q12 ;sum
296 vmlal.s16 q14, d24, d24 ;sse
297 vmlal.s16 q15, d25, d25
301 vpadal.s16 q13, q0 ;sum
302 vmlal.s16 q14, d0, d0 ;sse
303 vmlal.s16 q15, d1, d1
305 vpadal.s16 q13, q1 ;sum
306 vmlal.s16 q14, d2, d2 ;sse
307 vmlal.s16 q15, d3, d3
309 vpadal.s16 q13, q5 ;sum
310 vmlal.s16 q14, d10, d10 ;sse
311 vmlal.s16 q15, d11, d11
315 vpadal.s16 q13, q6 ;sum
316 vmlal.s16 q14, d12, d12 ;sse
317 vmlal.s16 q15, d13, d13
319 bne vp8_filt16x16s_4_4_loop_neon
321 vadd.u32 q15, q14, q15 ;accumulate sse
322 vpaddl.s32 q0, q13 ;accumulate sum
329 vst1.32 {d1[0]}, [lr] ;store sse
330 vshr.u32 d10, d10, #8
333 vmov.32 r0, d0[0] ;return
337 ;==============================
338 ; r0 unsigned char *src_ptr,
339 ; r1 int src_pixels_per_line,
342 ; stack unsigned char *dst_ptr,
343 ; stack int dst_pixels_per_line,
344 ; stack unsigned int *sse
345 ;note: in vp8_find_best_half_pixel_step()(called when 8<Speed<15), and first call of vp8_find_best_sub_pixel_step()
346 ;(called when speed<=8). xoffset/yoffset can only be 4 or 0, which means either by pass the filter,
347 ;or filter coeff is {64, 64}. This simplified program only works in this situation.
348 ;note: It happens that both xoffset and yoffset are zero. This can be handled in c code later.
350 |vp8_sub_pixel_variance16x16s_neon| PROC
353 ldr r4, [sp, #8] ;load *dst_ptr from stack
354 ldr r12, [sp, #12] ;load dst_pixels_per_line from stack
355 ldr lr, [sp, #16] ;load *sse from stack
357 cmp r2, #0 ;skip first_pass filter if xoffset=0
358 beq secondpass_bfilter16x16s_only
360 cmp r3, #0 ;skip second_pass filter if yoffset=0
361 beq firstpass_bfilter16x16s_only
363 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
364 sub sp, sp, #256 ;reserve space on stack for temporary storage
365 vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
367 mov r2, #4 ;loop counter
368 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
370 ;First Pass: output_height lines x output_width columns (17x16)
371 vp8e_filt_blk2d_fp16x16s_loop_neon
372 vld1.u8 {d4, d5, d6, d7}, [r0], r1
373 vld1.u8 {d8, d9, d10, d11}, [r0], r1
374 vld1.u8 {d12, d13, d14, d15}, [r0], r1
375 vld1.u8 {d16, d17, d18, d19}, [r0], r1
379 ;pld [r0, r1, lsl #1]
381 vext.8 q3, q2, q3, #1 ;construct src_ptr[1]
382 vext.8 q5, q4, q5, #1
383 vext.8 q7, q6, q7, #1
384 vext.8 q9, q8, q9, #1
386 vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
397 vst1.u8 {d0, d1 ,d2, d3}, [r3]! ;store result
399 vst1.u8 {d4, d5, d6, d7}, [r3]!
401 bne vp8e_filt_blk2d_fp16x16s_loop_neon
403 b sub_pixel_variance16x16s_neon
405 ;--------------------
406 firstpass_bfilter16x16s_only
407 mov r2, #2 ;loop counter
408 sub sp, sp, #256 ;reserve space on stack for temporary storage
411 ;First Pass: output_height lines x output_width columns (16x16)
412 vp8e_filt_blk2d_fpo16x16s_loop_neon
413 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
414 vld1.u8 {d4, d5, d6, d7}, [r0], r1
415 vld1.u8 {d8, d9, d10, d11}, [r0], r1
416 vld1.u8 {d12, d13, d14, d15}, [r0], r1
420 ;pld [r0, r1, lsl #1]
422 vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
423 vld1.u8 {d16, d17, d18, d19}, [r0], r1
424 vext.8 q3, q2, q3, #1
425 vld1.u8 {d20, d21, d22, d23}, [r0], r1
426 vext.8 q5, q4, q5, #1
427 vld1.u8 {d24, d25, d26, d27}, [r0], r1
428 vext.8 q7, q6, q7, #1
429 vld1.u8 {d28, d29, d30, d31}, [r0], r1
430 vext.8 q9, q8, q9, #1
431 vext.8 q11, q10, q11, #1
432 vext.8 q13, q12, q13, #1
433 vext.8 q15, q14, q15, #1
435 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
440 vrhadd.u8 q5, q10, q11
441 vrhadd.u8 q6, q12, q13
442 vrhadd.u8 q7, q14, q15
446 vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result
447 vst1.u8 {d4, d5, d6, d7}, [r3]!
448 vst1.u8 {d8, d9, d10, d11}, [r3]!
449 vst1.u8 {d12, d13, d14, d15}, [r3]!
451 bne vp8e_filt_blk2d_fpo16x16s_loop_neon
453 b sub_pixel_variance16x16s_neon
455 ;---------------------
456 secondpass_bfilter16x16s_only
457 sub sp, sp, #256 ;reserve space on stack for temporary storage
459 mov r2, #2 ;loop counter
460 vld1.u8 {d0, d1}, [r0], r1 ;load src data
463 vp8e_filt_blk2d_spo16x16s_loop_neon
464 vld1.u8 {d2, d3}, [r0], r1
465 vld1.u8 {d4, d5}, [r0], r1
466 vld1.u8 {d6, d7}, [r0], r1
467 vld1.u8 {d8, d9}, [r0], r1
470 vld1.u8 {d10, d11}, [r0], r1
472 vld1.u8 {d12, d13}, [r0], r1
474 vld1.u8 {d14, d15}, [r0], r1
476 vld1.u8 {d16, d17}, [r0], r1
484 vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result
486 vst1.u8 {d4, d5, d6, d7}, [r3]!
487 vst1.u8 {d8, d9, d10, d11}, [r3]! ;store result
488 vst1.u8 {d12, d13, d14, d15}, [r3]!
490 bne vp8e_filt_blk2d_spo16x16s_loop_neon
492 b sub_pixel_variance16x16s_neon
494 ;----------------------------
496 sub_pixel_variance16x16s_neon
497 vmov.i8 q8, #0 ;q8 - sum
498 vmov.i8 q9, #0 ;q9, q10 - sse
504 sub_pixel_variance16x16s_neon_loop
505 vld1.8 {q0}, [r3]! ;Load up source and reference
506 vld1.8 {q1}, [r4], r12
508 vld1.8 {q3}, [r4], r12
510 vld1.8 {q5}, [r4], r12
512 vld1.8 {q7}, [r4], r12
514 vsubl.u8 q11, d0, d2 ;diff
520 vsubl.u8 q2, d12, d14
521 vsubl.u8 q3, d13, d15
523 vpadal.s16 q8, q11 ;sum
524 vmlal.s16 q9, d22, d22 ;sse
525 vmlal.s16 q10, d23, d23
530 vmlal.s16 q9, d24, d24
531 vmlal.s16 q10, d25, d25
533 vmlal.s16 q9, d26, d26
534 vmlal.s16 q10, d27, d27
536 vmlal.s16 q9, d28, d28
537 vmlal.s16 q10, d29, d29
539 vpadal.s16 q8, q0 ;sum
540 vmlal.s16 q9, d0, d0 ;sse
541 vmlal.s16 q10, d1, d1
544 vmlal.s16 q10, d3, d3
547 vmlal.s16 q10, d5, d5
550 vmlal.s16 q10, d7, d7
552 bne sub_pixel_variance16x16s_neon_loop
554 vadd.u32 q10, q9, q10 ;accumulate sse
555 vpaddl.s32 q0, q8 ;accumulate sum
562 vst1.32 {d1[0]}, [lr] ;store sse
563 vshr.u32 d10, d10, #8
567 vmov.32 r0, d0[0] ;return