VP8 for ARMv8 by using NEON intrinsics 17

Add vp8_subpixelvariance_neon.c
- vp8_sub_pixel_variance16x16_neon_func
- vp8_variance_halfpixvar16x16_h_neon
- vp8_variance_halfpixvar16x16_v_neon
- vp8_variance_halfpixvar16x16_hv_neon
- vp8_sub_pixel_variance8x8_neon

Change-Id: I3e5d85b2eafc26be0eef6a777789b80e4579257b
Signed-off-by: James Yu <james.yu@linaro.org>
This commit is contained in:
Scott LaVarnway 2014-08-26 12:13:03 -07:00 committed by Johann
parent 5b788c0cbe
commit 9293d267d2
5 changed files with 1025 additions and 1236 deletions

View File

@ -1,425 +0,0 @@
;
; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
;
; Use of this source code is governed by a BSD-style license
; that can be found in the LICENSE file in the root of the source
; tree. An additional intellectual property rights grant can be found
; in the file PATENTS. All contributing project authors may
; be found in the AUTHORS file in the root of the source tree.
;
;-----------------
EXPORT |vp8_sub_pixel_variance16x16_neon_func|
ARM
REQUIRE8
PRESERVE8
AREA ||.text||, CODE, READONLY, ALIGN=2
; r0 unsigned char *src_ptr,
; r1 int src_pixels_per_line,
; r2 int xoffset,
; r3 int yoffset,
; stack(r4) unsigned char *dst_ptr,
; stack(r5) int dst_pixels_per_line,
; stack(r6) unsigned int *sse
;note: most of the code is copied from bilinear_predict16x16_neon and vp8_variance16x16_neon.
bilinear_taps_coeff
DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
|vp8_sub_pixel_variance16x16_neon_func| PROC
push {r4-r6, lr}
vpush {d8-d15}
adr r12, bilinear_taps_coeff
ldr r4, [sp, #80] ;load *dst_ptr from stack
ldr r5, [sp, #84] ;load dst_pixels_per_line from stack
ldr r6, [sp, #88] ;load *sse from stack
cmp r2, #0 ;skip first_pass filter if xoffset=0
beq secondpass_bfilter16x16_only
add r2, r12, r2, lsl #3 ;calculate filter location
cmp r3, #0 ;skip second_pass filter if yoffset=0
vld1.s32 {d31}, [r2] ;load first_pass filter
beq firstpass_bfilter16x16_only
sub sp, sp, #272 ;reserve space on stack for temporary storage
vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data
mov lr, sp
vld1.u8 {d5, d6, d7}, [r0], r1
mov r2, #3 ;loop counter
vld1.u8 {d8, d9, d10}, [r0], r1
vdup.8 d0, d31[0] ;first_pass filter (d0 d1)
vld1.u8 {d11, d12, d13}, [r0], r1
vdup.8 d1, d31[4]
;First Pass: output_height lines x output_width columns (17x16)
vp8e_filt_blk2d_fp16x16_loop_neon
pld [r0]
pld [r0, r1]
pld [r0, r1, lsl #1]
vmull.u8 q7, d2, d0 ;(src_ptr[0] * Filter[0])
vmull.u8 q8, d3, d0
vmull.u8 q9, d5, d0
vmull.u8 q10, d6, d0
vmull.u8 q11, d8, d0
vmull.u8 q12, d9, d0
vmull.u8 q13, d11, d0
vmull.u8 q14, d12, d0
vext.8 d2, d2, d3, #1 ;construct src_ptr[1]
vext.8 d5, d5, d6, #1
vext.8 d8, d8, d9, #1
vext.8 d11, d11, d12, #1
vmlal.u8 q7, d2, d1 ;(src_ptr[0] * Filter[1])
vmlal.u8 q9, d5, d1
vmlal.u8 q11, d8, d1
vmlal.u8 q13, d11, d1
vext.8 d3, d3, d4, #1
vext.8 d6, d6, d7, #1
vext.8 d9, d9, d10, #1
vext.8 d12, d12, d13, #1
vmlal.u8 q8, d3, d1 ;(src_ptr[0] * Filter[1])
vmlal.u8 q10, d6, d1
vmlal.u8 q12, d9, d1
vmlal.u8 q14, d12, d1
subs r2, r2, #1
vqrshrn.u16 d14, q7, #7 ;shift/round/saturate to u8
vqrshrn.u16 d15, q8, #7
vqrshrn.u16 d16, q9, #7
vqrshrn.u16 d17, q10, #7
vqrshrn.u16 d18, q11, #7
vqrshrn.u16 d19, q12, #7
vqrshrn.u16 d20, q13, #7
vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data
vqrshrn.u16 d21, q14, #7
vld1.u8 {d5, d6, d7}, [r0], r1
vst1.u8 {d14, d15, d16, d17}, [lr]! ;store result
vld1.u8 {d8, d9, d10}, [r0], r1
vst1.u8 {d18, d19, d20, d21}, [lr]!
vld1.u8 {d11, d12, d13}, [r0], r1
bne vp8e_filt_blk2d_fp16x16_loop_neon
;First-pass filtering for rest 5 lines
vld1.u8 {d14, d15, d16}, [r0], r1
vmull.u8 q9, d2, d0 ;(src_ptr[0] * Filter[0])
vmull.u8 q10, d3, d0
vmull.u8 q11, d5, d0
vmull.u8 q12, d6, d0
vmull.u8 q13, d8, d0
vmull.u8 q14, d9, d0
vext.8 d2, d2, d3, #1 ;construct src_ptr[1]
vext.8 d5, d5, d6, #1
vext.8 d8, d8, d9, #1
vmlal.u8 q9, d2, d1 ;(src_ptr[0] * Filter[1])
vmlal.u8 q11, d5, d1
vmlal.u8 q13, d8, d1
vext.8 d3, d3, d4, #1
vext.8 d6, d6, d7, #1
vext.8 d9, d9, d10, #1
vmlal.u8 q10, d3, d1 ;(src_ptr[0] * Filter[1])
vmlal.u8 q12, d6, d1
vmlal.u8 q14, d9, d1
vmull.u8 q1, d11, d0
vmull.u8 q2, d12, d0
vmull.u8 q3, d14, d0
vmull.u8 q4, d15, d0
vext.8 d11, d11, d12, #1 ;construct src_ptr[1]
vext.8 d14, d14, d15, #1
vmlal.u8 q1, d11, d1 ;(src_ptr[0] * Filter[1])
vmlal.u8 q3, d14, d1
vext.8 d12, d12, d13, #1
vext.8 d15, d15, d16, #1
vmlal.u8 q2, d12, d1 ;(src_ptr[0] * Filter[1])
vmlal.u8 q4, d15, d1
vqrshrn.u16 d10, q9, #7 ;shift/round/saturate to u8
vqrshrn.u16 d11, q10, #7
vqrshrn.u16 d12, q11, #7
vqrshrn.u16 d13, q12, #7
vqrshrn.u16 d14, q13, #7
vqrshrn.u16 d15, q14, #7
vqrshrn.u16 d16, q1, #7
vqrshrn.u16 d17, q2, #7
vqrshrn.u16 d18, q3, #7
vqrshrn.u16 d19, q4, #7
vst1.u8 {d10, d11, d12, d13}, [lr]! ;store result
vst1.u8 {d14, d15, d16, d17}, [lr]!
vst1.u8 {d18, d19}, [lr]!
;Second pass: 16x16
;secondpass_filter
add r3, r12, r3, lsl #3
sub lr, lr, #272
vld1.u32 {d31}, [r3] ;load second_pass filter
sub sp, sp, #256
mov r3, sp
vld1.u8 {d22, d23}, [lr]! ;load src data
vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1)
vdup.8 d1, d31[4]
mov r12, #4 ;loop counter
vp8e_filt_blk2d_sp16x16_loop_neon
vld1.u8 {d24, d25}, [lr]!
vmull.u8 q1, d22, d0 ;(src_ptr[0] * Filter[0])
vld1.u8 {d26, d27}, [lr]!
vmull.u8 q2, d23, d0
vld1.u8 {d28, d29}, [lr]!
vmull.u8 q3, d24, d0
vld1.u8 {d30, d31}, [lr]!
vmull.u8 q4, d25, d0
vmull.u8 q5, d26, d0
vmull.u8 q6, d27, d0
vmull.u8 q7, d28, d0
vmull.u8 q8, d29, d0
vmlal.u8 q1, d24, d1 ;(src_ptr[pixel_step] * Filter[1])
vmlal.u8 q2, d25, d1
vmlal.u8 q3, d26, d1
vmlal.u8 q4, d27, d1
vmlal.u8 q5, d28, d1
vmlal.u8 q6, d29, d1
vmlal.u8 q7, d30, d1
vmlal.u8 q8, d31, d1
subs r12, r12, #1
vqrshrn.u16 d2, q1, #7 ;shift/round/saturate to u8
vqrshrn.u16 d3, q2, #7
vqrshrn.u16 d4, q3, #7
vqrshrn.u16 d5, q4, #7
vqrshrn.u16 d6, q5, #7
vqrshrn.u16 d7, q6, #7
vqrshrn.u16 d8, q7, #7
vqrshrn.u16 d9, q8, #7
vst1.u8 {d2, d3}, [r3]! ;store result
vst1.u8 {d4, d5}, [r3]!
vst1.u8 {d6, d7}, [r3]!
vmov q11, q15
vst1.u8 {d8, d9}, [r3]!
bne vp8e_filt_blk2d_sp16x16_loop_neon
b sub_pixel_variance16x16_neon
;--------------------
firstpass_bfilter16x16_only
mov r2, #4 ;loop counter
sub sp, sp, #528 ;reserve space on stack for temporary storage
vdup.8 d0, d31[0] ;first_pass filter (d0 d1)
vdup.8 d1, d31[4]
mov r3, sp
;First Pass: output_height lines x output_width columns (16x16)
vp8e_filt_blk2d_fpo16x16_loop_neon
vld1.u8 {d2, d3, d4}, [r0], r1 ;load src data
vld1.u8 {d5, d6, d7}, [r0], r1
vld1.u8 {d8, d9, d10}, [r0], r1
vld1.u8 {d11, d12, d13}, [r0], r1
pld [r0]
pld [r0, r1]
pld [r0, r1, lsl #1]
vmull.u8 q7, d2, d0 ;(src_ptr[0] * Filter[0])
vmull.u8 q8, d3, d0
vmull.u8 q9, d5, d0
vmull.u8 q10, d6, d0
vmull.u8 q11, d8, d0
vmull.u8 q12, d9, d0
vmull.u8 q13, d11, d0
vmull.u8 q14, d12, d0
vext.8 d2, d2, d3, #1 ;construct src_ptr[1]
vext.8 d5, d5, d6, #1
vext.8 d8, d8, d9, #1
vext.8 d11, d11, d12, #1
vmlal.u8 q7, d2, d1 ;(src_ptr[0] * Filter[1])
vmlal.u8 q9, d5, d1
vmlal.u8 q11, d8, d1
vmlal.u8 q13, d11, d1
vext.8 d3, d3, d4, #1
vext.8 d6, d6, d7, #1
vext.8 d9, d9, d10, #1
vext.8 d12, d12, d13, #1
vmlal.u8 q8, d3, d1 ;(src_ptr[0] * Filter[1])
vmlal.u8 q10, d6, d1
vmlal.u8 q12, d9, d1
vmlal.u8 q14, d12, d1
subs r2, r2, #1
vqrshrn.u16 d14, q7, #7 ;shift/round/saturate to u8
vqrshrn.u16 d15, q8, #7
vqrshrn.u16 d16, q9, #7
vqrshrn.u16 d17, q10, #7
vqrshrn.u16 d18, q11, #7
vqrshrn.u16 d19, q12, #7
vqrshrn.u16 d20, q13, #7
vst1.u8 {d14, d15}, [r3]! ;store result
vqrshrn.u16 d21, q14, #7
vst1.u8 {d16, d17}, [r3]!
vst1.u8 {d18, d19}, [r3]!
vst1.u8 {d20, d21}, [r3]!
bne vp8e_filt_blk2d_fpo16x16_loop_neon
b sub_pixel_variance16x16_neon
;---------------------
secondpass_bfilter16x16_only
;Second pass: 16x16
;secondpass_filter
sub sp, sp, #528 ;reserve space on stack for temporary storage
add r3, r12, r3, lsl #3
mov r12, #4 ;loop counter
vld1.u32 {d31}, [r3] ;load second_pass filter
vld1.u8 {d22, d23}, [r0], r1 ;load src data
mov r3, sp
vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1)
vdup.8 d1, d31[4]
vp8e_filt_blk2d_spo16x16_loop_neon
vld1.u8 {d24, d25}, [r0], r1
vmull.u8 q1, d22, d0 ;(src_ptr[0] * Filter[0])
vld1.u8 {d26, d27}, [r0], r1
vmull.u8 q2, d23, d0
vld1.u8 {d28, d29}, [r0], r1
vmull.u8 q3, d24, d0
vld1.u8 {d30, d31}, [r0], r1
vmull.u8 q4, d25, d0
vmull.u8 q5, d26, d0
vmull.u8 q6, d27, d0
vmull.u8 q7, d28, d0
vmull.u8 q8, d29, d0
vmlal.u8 q1, d24, d1 ;(src_ptr[pixel_step] * Filter[1])
vmlal.u8 q2, d25, d1
vmlal.u8 q3, d26, d1
vmlal.u8 q4, d27, d1
vmlal.u8 q5, d28, d1
vmlal.u8 q6, d29, d1
vmlal.u8 q7, d30, d1
vmlal.u8 q8, d31, d1
vqrshrn.u16 d2, q1, #7 ;shift/round/saturate to u8
vqrshrn.u16 d3, q2, #7
vqrshrn.u16 d4, q3, #7
vqrshrn.u16 d5, q4, #7
vqrshrn.u16 d6, q5, #7
vqrshrn.u16 d7, q6, #7
vqrshrn.u16 d8, q7, #7
vqrshrn.u16 d9, q8, #7
vst1.u8 {d2, d3}, [r3]! ;store result
subs r12, r12, #1
vst1.u8 {d4, d5}, [r3]!
vmov q11, q15
vst1.u8 {d6, d7}, [r3]!
vst1.u8 {d8, d9}, [r3]!
bne vp8e_filt_blk2d_spo16x16_loop_neon
b sub_pixel_variance16x16_neon
;----------------------------
;variance16x16
sub_pixel_variance16x16_neon
vmov.i8 q8, #0 ;q8 - sum
vmov.i8 q9, #0 ;q9, q10 - sse
vmov.i8 q10, #0
sub r3, r3, #256
mov r12, #8
sub_pixel_variance16x16_neon_loop
vld1.8 {q0}, [r3]! ;Load up source and reference
vld1.8 {q2}, [r4], r5
vld1.8 {q1}, [r3]!
vld1.8 {q3}, [r4], r5
vsubl.u8 q11, d0, d4 ;diff
vsubl.u8 q12, d1, d5
vsubl.u8 q13, d2, d6
vsubl.u8 q14, d3, d7
vpadal.s16 q8, q11 ;sum
vmlal.s16 q9, d22, d22 ;sse
vmlal.s16 q10, d23, d23
subs r12, r12, #1
vpadal.s16 q8, q12
vmlal.s16 q9, d24, d24
vmlal.s16 q10, d25, d25
vpadal.s16 q8, q13
vmlal.s16 q9, d26, d26
vmlal.s16 q10, d27, d27
vpadal.s16 q8, q14
vmlal.s16 q9, d28, d28
vmlal.s16 q10, d29, d29
bne sub_pixel_variance16x16_neon_loop
vadd.u32 q10, q9, q10 ;accumulate sse
vpaddl.s32 q0, q8 ;accumulate sum
vpaddl.u32 q1, q10
vadd.s64 d0, d0, d1
vadd.u64 d1, d2, d3
vmull.s32 q5, d0, d0
vst1.32 {d1[0]}, [r6] ;store sse
vshr.u32 d10, d10, #8
vsub.u32 d0, d1, d10
add sp, sp, #528
vmov.32 r0, d0[0] ;return
vpop {d8-d15}
pop {r4-r6,pc}
ENDP
END

View File

@ -1,583 +0,0 @@
;
; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
;
; Use of this source code is governed by a BSD-style license
; that can be found in the LICENSE file in the root of the source
; tree. An additional intellectual property rights grant can be found
; in the file PATENTS. All contributing project authors may
; be found in the AUTHORS file in the root of the source tree.
;
EXPORT |vp8_variance_halfpixvar16x16_h_neon|
EXPORT |vp8_variance_halfpixvar16x16_v_neon|
EXPORT |vp8_variance_halfpixvar16x16_hv_neon|
EXPORT |vp8_sub_pixel_variance16x16s_neon|
ARM
REQUIRE8
PRESERVE8
AREA ||.text||, CODE, READONLY, ALIGN=2
;================================================
;unsigned int vp8_variance_halfpixvar16x16_h_neon
;(
; unsigned char *src_ptr, r0
; int src_pixels_per_line, r1
; unsigned char *dst_ptr, r2
; int dst_pixels_per_line, r3
; unsigned int *sse
;);
;================================================
|vp8_variance_halfpixvar16x16_h_neon| PROC
push {lr}
vpush {d8-d15}
mov r12, #4 ;loop counter
ldr lr, [sp, #68] ;load *sse from stack
vmov.i8 q8, #0 ;q8 - sum
vmov.i8 q9, #0 ;q9, q10 - sse
vmov.i8 q10, #0
;First Pass: output_height lines x output_width columns (16x16)
vp8_filt_fpo16x16s_4_0_loop_neon
vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
vld1.8 {q11}, [r2], r3
vld1.u8 {d4, d5, d6, d7}, [r0], r1
vld1.8 {q12}, [r2], r3
vld1.u8 {d8, d9, d10, d11}, [r0], r1
vld1.8 {q13}, [r2], r3
vld1.u8 {d12, d13, d14, d15}, [r0], r1
;pld [r0]
;pld [r0, r1]
;pld [r0, r1, lsl #1]
vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
vext.8 q3, q2, q3, #1
vext.8 q5, q4, q5, #1
vext.8 q7, q6, q7, #1
vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
vld1.8 {q14}, [r2], r3
vrhadd.u8 q1, q2, q3
vrhadd.u8 q2, q4, q5
vrhadd.u8 q3, q6, q7
vsubl.u8 q4, d0, d22 ;diff
vsubl.u8 q5, d1, d23
vsubl.u8 q6, d2, d24
vsubl.u8 q7, d3, d25
vsubl.u8 q0, d4, d26
vsubl.u8 q1, d5, d27
vsubl.u8 q2, d6, d28
vsubl.u8 q3, d7, d29
vpadal.s16 q8, q4 ;sum
vmlal.s16 q9, d8, d8 ;sse
vmlal.s16 q10, d9, d9
subs r12, r12, #1
vpadal.s16 q8, q5
vmlal.s16 q9, d10, d10
vmlal.s16 q10, d11, d11
vpadal.s16 q8, q6
vmlal.s16 q9, d12, d12
vmlal.s16 q10, d13, d13
vpadal.s16 q8, q7
vmlal.s16 q9, d14, d14
vmlal.s16 q10, d15, d15
vpadal.s16 q8, q0 ;sum
vmlal.s16 q9, d0, d0 ;sse
vmlal.s16 q10, d1, d1
vpadal.s16 q8, q1
vmlal.s16 q9, d2, d2
vmlal.s16 q10, d3, d3
vpadal.s16 q8, q2
vmlal.s16 q9, d4, d4
vmlal.s16 q10, d5, d5
vpadal.s16 q8, q3
vmlal.s16 q9, d6, d6
vmlal.s16 q10, d7, d7
bne vp8_filt_fpo16x16s_4_0_loop_neon
vadd.u32 q10, q9, q10 ;accumulate sse
vpaddl.s32 q0, q8 ;accumulate sum
vpaddl.u32 q1, q10
vadd.s64 d0, d0, d1
vadd.u64 d1, d2, d3
vmull.s32 q5, d0, d0
vst1.32 {d1[0]}, [lr] ;store sse
vshr.u32 d10, d10, #8
vsub.u32 d0, d1, d10
vmov.32 r0, d0[0] ;return
vpop {d8-d15}
pop {pc}
ENDP
;================================================
;unsigned int vp8_variance_halfpixvar16x16_v_neon
;(
; unsigned char *src_ptr, r0
; int src_pixels_per_line, r1
; unsigned char *dst_ptr, r2
; int dst_pixels_per_line, r3
; unsigned int *sse
;);
;================================================
|vp8_variance_halfpixvar16x16_v_neon| PROC
push {lr}
vpush {d8-d15}
mov r12, #4 ;loop counter
vld1.u8 {q0}, [r0], r1 ;load src data
ldr lr, [sp, #68] ;load *sse from stack
vmov.i8 q8, #0 ;q8 - sum
vmov.i8 q9, #0 ;q9, q10 - sse
vmov.i8 q10, #0
vp8_filt_spo16x16s_0_4_loop_neon
vld1.u8 {q2}, [r0], r1
vld1.8 {q1}, [r2], r3
vld1.u8 {q4}, [r0], r1
vld1.8 {q3}, [r2], r3
vld1.u8 {q6}, [r0], r1
vld1.8 {q5}, [r2], r3
vld1.u8 {q15}, [r0], r1
vrhadd.u8 q0, q0, q2
vld1.8 {q7}, [r2], r3
vrhadd.u8 q2, q2, q4
vrhadd.u8 q4, q4, q6
vrhadd.u8 q6, q6, q15
vsubl.u8 q11, d0, d2 ;diff
vsubl.u8 q12, d1, d3
vsubl.u8 q13, d4, d6
vsubl.u8 q14, d5, d7
vsubl.u8 q0, d8, d10
vsubl.u8 q1, d9, d11
vsubl.u8 q2, d12, d14
vsubl.u8 q3, d13, d15
vpadal.s16 q8, q11 ;sum
vmlal.s16 q9, d22, d22 ;sse
vmlal.s16 q10, d23, d23
subs r12, r12, #1
vpadal.s16 q8, q12
vmlal.s16 q9, d24, d24
vmlal.s16 q10, d25, d25
vpadal.s16 q8, q13
vmlal.s16 q9, d26, d26
vmlal.s16 q10, d27, d27
vpadal.s16 q8, q14
vmlal.s16 q9, d28, d28
vmlal.s16 q10, d29, d29
vpadal.s16 q8, q0 ;sum
vmlal.s16 q9, d0, d0 ;sse
vmlal.s16 q10, d1, d1
vpadal.s16 q8, q1
vmlal.s16 q9, d2, d2
vmlal.s16 q10, d3, d3
vpadal.s16 q8, q2
vmlal.s16 q9, d4, d4
vmlal.s16 q10, d5, d5
vmov q0, q15
vpadal.s16 q8, q3
vmlal.s16 q9, d6, d6
vmlal.s16 q10, d7, d7
bne vp8_filt_spo16x16s_0_4_loop_neon
vadd.u32 q10, q9, q10 ;accumulate sse
vpaddl.s32 q0, q8 ;accumulate sum
vpaddl.u32 q1, q10
vadd.s64 d0, d0, d1
vadd.u64 d1, d2, d3
vmull.s32 q5, d0, d0
vst1.32 {d1[0]}, [lr] ;store sse
vshr.u32 d10, d10, #8
vsub.u32 d0, d1, d10
vmov.32 r0, d0[0] ;return
vpop {d8-d15}
pop {pc}
ENDP
;================================================
;unsigned int vp8_variance_halfpixvar16x16_hv_neon
;(
; unsigned char *src_ptr, r0
; int src_pixels_per_line, r1
; unsigned char *dst_ptr, r2
; int dst_pixels_per_line, r3
; unsigned int *sse
;);
;================================================
|vp8_variance_halfpixvar16x16_hv_neon| PROC
push {lr}
vpush {d8-d15}
vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
ldr lr, [sp, #68] ;load *sse from stack
vmov.i8 q13, #0 ;q8 - sum
vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
vmov.i8 q14, #0 ;q9, q10 - sse
vmov.i8 q15, #0
mov r12, #4 ;loop counter
vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
;First Pass: output_height lines x output_width columns (17x16)
vp8_filt16x16s_4_4_loop_neon
vld1.u8 {d4, d5, d6, d7}, [r0], r1
vld1.u8 {d8, d9, d10, d11}, [r0], r1
vld1.u8 {d12, d13, d14, d15}, [r0], r1
vld1.u8 {d16, d17, d18, d19}, [r0], r1
;pld [r0]
;pld [r0, r1]
;pld [r0, r1, lsl #1]
vext.8 q3, q2, q3, #1 ;construct src_ptr[1]
vext.8 q5, q4, q5, #1
vext.8 q7, q6, q7, #1
vext.8 q9, q8, q9, #1
vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
vrhadd.u8 q2, q4, q5
vrhadd.u8 q3, q6, q7
vrhadd.u8 q4, q8, q9
vld1.8 {q5}, [r2], r3
vrhadd.u8 q0, q0, q1
vld1.8 {q6}, [r2], r3
vrhadd.u8 q1, q1, q2
vld1.8 {q7}, [r2], r3
vrhadd.u8 q2, q2, q3
vld1.8 {q8}, [r2], r3
vrhadd.u8 q3, q3, q4
vsubl.u8 q9, d0, d10 ;diff
vsubl.u8 q10, d1, d11
vsubl.u8 q11, d2, d12
vsubl.u8 q12, d3, d13
vsubl.u8 q0, d4, d14 ;diff
vsubl.u8 q1, d5, d15
vsubl.u8 q5, d6, d16
vsubl.u8 q6, d7, d17
vpadal.s16 q13, q9 ;sum
vmlal.s16 q14, d18, d18 ;sse
vmlal.s16 q15, d19, d19
vpadal.s16 q13, q10 ;sum
vmlal.s16 q14, d20, d20 ;sse
vmlal.s16 q15, d21, d21
vpadal.s16 q13, q11 ;sum
vmlal.s16 q14, d22, d22 ;sse
vmlal.s16 q15, d23, d23
vpadal.s16 q13, q12 ;sum
vmlal.s16 q14, d24, d24 ;sse
vmlal.s16 q15, d25, d25
subs r12, r12, #1
vpadal.s16 q13, q0 ;sum
vmlal.s16 q14, d0, d0 ;sse
vmlal.s16 q15, d1, d1
vpadal.s16 q13, q1 ;sum
vmlal.s16 q14, d2, d2 ;sse
vmlal.s16 q15, d3, d3
vpadal.s16 q13, q5 ;sum
vmlal.s16 q14, d10, d10 ;sse
vmlal.s16 q15, d11, d11
vmov q0, q4
vpadal.s16 q13, q6 ;sum
vmlal.s16 q14, d12, d12 ;sse
vmlal.s16 q15, d13, d13
bne vp8_filt16x16s_4_4_loop_neon
vadd.u32 q15, q14, q15 ;accumulate sse
vpaddl.s32 q0, q13 ;accumulate sum
vpaddl.u32 q1, q15
vadd.s64 d0, d0, d1
vadd.u64 d1, d2, d3
vmull.s32 q5, d0, d0
vst1.32 {d1[0]}, [lr] ;store sse
vshr.u32 d10, d10, #8
vsub.u32 d0, d1, d10
vmov.32 r0, d0[0] ;return
vpop {d8-d15}
pop {pc}
ENDP
;==============================
; r0 unsigned char *src_ptr,
; r1 int src_pixels_per_line,
; r2 int xoffset,
; r3 int yoffset,
; stack unsigned char *dst_ptr,
; stack int dst_pixels_per_line,
; stack unsigned int *sse
;note: in vp8_find_best_half_pixel_step()(called when 8<Speed<15), and first call of vp8_find_best_sub_pixel_step()
;(called when speed<=8). xoffset/yoffset can only be 4 or 0, which means either by pass the filter,
;or filter coeff is {64, 64}. This simplified program only works in this situation.
;note: It happens that both xoffset and yoffset are zero. This can be handled in c code later.
|vp8_sub_pixel_variance16x16s_neon| PROC
push {r4, lr}
vpush {d8-d15}
ldr r4, [sp, #72] ;load *dst_ptr from stack
ldr r12, [sp, #76] ;load dst_pixels_per_line from stack
ldr lr, [sp, #80] ;load *sse from stack
cmp r2, #0 ;skip first_pass filter if xoffset=0
beq secondpass_bfilter16x16s_only
cmp r3, #0 ;skip second_pass filter if yoffset=0
beq firstpass_bfilter16x16s_only
vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
sub sp, sp, #256 ;reserve space on stack for temporary storage
vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
mov r3, sp
mov r2, #4 ;loop counter
vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
;First Pass: output_height lines x output_width columns (17x16)
vp8e_filt_blk2d_fp16x16s_loop_neon
vld1.u8 {d4, d5, d6, d7}, [r0], r1
vld1.u8 {d8, d9, d10, d11}, [r0], r1
vld1.u8 {d12, d13, d14, d15}, [r0], r1
vld1.u8 {d16, d17, d18, d19}, [r0], r1
;pld [r0]
;pld [r0, r1]
;pld [r0, r1, lsl #1]
vext.8 q3, q2, q3, #1 ;construct src_ptr[1]
vext.8 q5, q4, q5, #1
vext.8 q7, q6, q7, #1
vext.8 q9, q8, q9, #1
vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
vrhadd.u8 q2, q4, q5
vrhadd.u8 q3, q6, q7
vrhadd.u8 q4, q8, q9
vrhadd.u8 q0, q0, q1
vrhadd.u8 q1, q1, q2
vrhadd.u8 q2, q2, q3
vrhadd.u8 q3, q3, q4
subs r2, r2, #1
vst1.u8 {d0, d1 ,d2, d3}, [r3]! ;store result
vmov q0, q4
vst1.u8 {d4, d5, d6, d7}, [r3]!
bne vp8e_filt_blk2d_fp16x16s_loop_neon
b sub_pixel_variance16x16s_neon
;--------------------
firstpass_bfilter16x16s_only
mov r2, #2 ;loop counter
sub sp, sp, #256 ;reserve space on stack for temporary storage
mov r3, sp
;First Pass: output_height lines x output_width columns (16x16)
vp8e_filt_blk2d_fpo16x16s_loop_neon
vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data
vld1.u8 {d4, d5, d6, d7}, [r0], r1
vld1.u8 {d8, d9, d10, d11}, [r0], r1
vld1.u8 {d12, d13, d14, d15}, [r0], r1
;pld [r0]
;pld [r0, r1]
;pld [r0, r1, lsl #1]
vext.8 q1, q0, q1, #1 ;construct src_ptr[1]
vld1.u8 {d16, d17, d18, d19}, [r0], r1
vext.8 q3, q2, q3, #1
vld1.u8 {d20, d21, d22, d23}, [r0], r1
vext.8 q5, q4, q5, #1
vld1.u8 {d24, d25, d26, d27}, [r0], r1
vext.8 q7, q6, q7, #1
vld1.u8 {d28, d29, d30, d31}, [r0], r1
vext.8 q9, q8, q9, #1
vext.8 q11, q10, q11, #1
vext.8 q13, q12, q13, #1
vext.8 q15, q14, q15, #1
vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1
vrhadd.u8 q1, q2, q3
vrhadd.u8 q2, q4, q5
vrhadd.u8 q3, q6, q7
vrhadd.u8 q4, q8, q9
vrhadd.u8 q5, q10, q11
vrhadd.u8 q6, q12, q13
vrhadd.u8 q7, q14, q15
subs r2, r2, #1
vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result
vst1.u8 {d4, d5, d6, d7}, [r3]!
vst1.u8 {d8, d9, d10, d11}, [r3]!
vst1.u8 {d12, d13, d14, d15}, [r3]!
bne vp8e_filt_blk2d_fpo16x16s_loop_neon
b sub_pixel_variance16x16s_neon
;---------------------
secondpass_bfilter16x16s_only
sub sp, sp, #256 ;reserve space on stack for temporary storage
mov r2, #2 ;loop counter
vld1.u8 {d0, d1}, [r0], r1 ;load src data
mov r3, sp
vp8e_filt_blk2d_spo16x16s_loop_neon
vld1.u8 {d2, d3}, [r0], r1
vld1.u8 {d4, d5}, [r0], r1
vld1.u8 {d6, d7}, [r0], r1
vld1.u8 {d8, d9}, [r0], r1
vrhadd.u8 q0, q0, q1
vld1.u8 {d10, d11}, [r0], r1
vrhadd.u8 q1, q1, q2
vld1.u8 {d12, d13}, [r0], r1
vrhadd.u8 q2, q2, q3
vld1.u8 {d14, d15}, [r0], r1
vrhadd.u8 q3, q3, q4
vld1.u8 {d16, d17}, [r0], r1
vrhadd.u8 q4, q4, q5
vrhadd.u8 q5, q5, q6
vrhadd.u8 q6, q6, q7
vrhadd.u8 q7, q7, q8
subs r2, r2, #1
vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result
vmov q0, q8
vst1.u8 {d4, d5, d6, d7}, [r3]!
vst1.u8 {d8, d9, d10, d11}, [r3]! ;store result
vst1.u8 {d12, d13, d14, d15}, [r3]!
bne vp8e_filt_blk2d_spo16x16s_loop_neon
b sub_pixel_variance16x16s_neon
;----------------------------
;variance16x16
sub_pixel_variance16x16s_neon
vmov.i8 q8, #0 ;q8 - sum
vmov.i8 q9, #0 ;q9, q10 - sse
vmov.i8 q10, #0
sub r3, r3, #256
mov r2, #4
sub_pixel_variance16x16s_neon_loop
vld1.8 {q0}, [r3]! ;Load up source and reference
vld1.8 {q1}, [r4], r12
vld1.8 {q2}, [r3]!
vld1.8 {q3}, [r4], r12
vld1.8 {q4}, [r3]!
vld1.8 {q5}, [r4], r12
vld1.8 {q6}, [r3]!
vld1.8 {q7}, [r4], r12
vsubl.u8 q11, d0, d2 ;diff
vsubl.u8 q12, d1, d3
vsubl.u8 q13, d4, d6
vsubl.u8 q14, d5, d7
vsubl.u8 q0, d8, d10
vsubl.u8 q1, d9, d11
vsubl.u8 q2, d12, d14
vsubl.u8 q3, d13, d15
vpadal.s16 q8, q11 ;sum
vmlal.s16 q9, d22, d22 ;sse
vmlal.s16 q10, d23, d23
subs r2, r2, #1
vpadal.s16 q8, q12
vmlal.s16 q9, d24, d24
vmlal.s16 q10, d25, d25
vpadal.s16 q8, q13
vmlal.s16 q9, d26, d26
vmlal.s16 q10, d27, d27
vpadal.s16 q8, q14
vmlal.s16 q9, d28, d28
vmlal.s16 q10, d29, d29
vpadal.s16 q8, q0 ;sum
vmlal.s16 q9, d0, d0 ;sse
vmlal.s16 q10, d1, d1
vpadal.s16 q8, q1
vmlal.s16 q9, d2, d2
vmlal.s16 q10, d3, d3
vpadal.s16 q8, q2
vmlal.s16 q9, d4, d4
vmlal.s16 q10, d5, d5
vpadal.s16 q8, q3
vmlal.s16 q9, d6, d6
vmlal.s16 q10, d7, d7
bne sub_pixel_variance16x16s_neon_loop
vadd.u32 q10, q9, q10 ;accumulate sse
vpaddl.s32 q0, q8 ;accumulate sum
vpaddl.u32 q1, q10
vadd.s64 d0, d0, d1
vadd.u64 d1, d2, d3
vmull.s32 q5, d0, d0
vst1.32 {d1[0]}, [lr] ;store sse
vshr.u32 d10, d10, #8
vsub.u32 d0, d1, d10
add sp, sp, #256
vmov.32 r0, d0[0] ;return
vpop {d8-d15}
pop {r4, pc}
ENDP
END

View File

@ -1,225 +0,0 @@
;
; Copyright (c) 2010 The WebM project authors. All Rights Reserved.
;
; Use of this source code is governed by a BSD-style license
; that can be found in the LICENSE file in the root of the source
; tree. An additional intellectual property rights grant can be found
; in the file PATENTS. All contributing project authors may
; be found in the AUTHORS file in the root of the source tree.
;
EXPORT |vp8_sub_pixel_variance8x8_neon|
ARM
REQUIRE8
PRESERVE8
AREA ||.text||, CODE, READONLY, ALIGN=2
; r0 unsigned char *src_ptr,
; r1 int src_pixels_per_line,
; r2 int xoffset,
; r3 int yoffset,
; stack(r4) unsigned char *dst_ptr,
; stack(r5) int dst_pixels_per_line,
; stack(r6) unsigned int *sse
;note: most of the code is copied from bilinear_predict8x8_neon and vp8_variance8x8_neon.
|vp8_sub_pixel_variance8x8_neon| PROC
push {r4-r5, lr}
vpush {d8-d15}
adr r12, bilinear_taps_coeff
ldr r4, [sp, #76] ;load *dst_ptr from stack
ldr r5, [sp, #80] ;load dst_pixels_per_line from stack
ldr lr, [sp, #84] ;load *sse from stack
cmp r2, #0 ;skip first_pass filter if xoffset=0
beq skip_firstpass_filter
;First pass: output_height lines x output_width columns (9x8)
add r2, r12, r2, lsl #3 ;calculate filter location
vld1.u8 {q1}, [r0], r1 ;load src data
vld1.u32 {d31}, [r2] ;load first_pass filter
vld1.u8 {q2}, [r0], r1
vdup.8 d0, d31[0] ;first_pass filter (d0 d1)
vld1.u8 {q3}, [r0], r1
vdup.8 d1, d31[4]
vld1.u8 {q4}, [r0], r1
vmull.u8 q6, d2, d0 ;(src_ptr[0] * Filter[0])
vmull.u8 q7, d4, d0
vmull.u8 q8, d6, d0
vmull.u8 q9, d8, d0
vext.8 d3, d2, d3, #1 ;construct src_ptr[-1]
vext.8 d5, d4, d5, #1
vext.8 d7, d6, d7, #1
vext.8 d9, d8, d9, #1
vmlal.u8 q6, d3, d1 ;(src_ptr[1] * Filter[1])
vmlal.u8 q7, d5, d1
vmlal.u8 q8, d7, d1
vmlal.u8 q9, d9, d1
vld1.u8 {q1}, [r0], r1 ;load src data
vqrshrn.u16 d22, q6, #7 ;shift/round/saturate to u8
vld1.u8 {q2}, [r0], r1
vqrshrn.u16 d23, q7, #7
vld1.u8 {q3}, [r0], r1
vqrshrn.u16 d24, q8, #7
vld1.u8 {q4}, [r0], r1
vqrshrn.u16 d25, q9, #7
;first_pass filtering on the rest 5-line data
vld1.u8 {q5}, [r0], r1
vmull.u8 q6, d2, d0 ;(src_ptr[0] * Filter[0])
vmull.u8 q7, d4, d0
vmull.u8 q8, d6, d0
vmull.u8 q9, d8, d0
vmull.u8 q10, d10, d0
vext.8 d3, d2, d3, #1 ;construct src_ptr[-1]
vext.8 d5, d4, d5, #1
vext.8 d7, d6, d7, #1
vext.8 d9, d8, d9, #1
vext.8 d11, d10, d11, #1
vmlal.u8 q6, d3, d1 ;(src_ptr[1] * Filter[1])
vmlal.u8 q7, d5, d1
vmlal.u8 q8, d7, d1
vmlal.u8 q9, d9, d1
vmlal.u8 q10, d11, d1
vqrshrn.u16 d26, q6, #7 ;shift/round/saturate to u8
vqrshrn.u16 d27, q7, #7
vqrshrn.u16 d28, q8, #7
vqrshrn.u16 d29, q9, #7
vqrshrn.u16 d30, q10, #7
;Second pass: 8x8
secondpass_filter
cmp r3, #0 ;skip second_pass filter if yoffset=0
;skip_secondpass_filter
beq sub_pixel_variance8x8_neon
add r3, r12, r3, lsl #3
vld1.u32 {d31}, [r3] ;load second_pass filter
vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1)
vdup.8 d1, d31[4]
vmull.u8 q1, d22, d0 ;(src_ptr[0] * Filter[0])
vmull.u8 q2, d23, d0
vmull.u8 q3, d24, d0
vmull.u8 q4, d25, d0
vmull.u8 q5, d26, d0
vmull.u8 q6, d27, d0
vmull.u8 q7, d28, d0
vmull.u8 q8, d29, d0
vmlal.u8 q1, d23, d1 ;(src_ptr[pixel_step] * Filter[1])
vmlal.u8 q2, d24, d1
vmlal.u8 q3, d25, d1
vmlal.u8 q4, d26, d1
vmlal.u8 q5, d27, d1
vmlal.u8 q6, d28, d1
vmlal.u8 q7, d29, d1
vmlal.u8 q8, d30, d1
vqrshrn.u16 d22, q1, #7 ;shift/round/saturate to u8
vqrshrn.u16 d23, q2, #7
vqrshrn.u16 d24, q3, #7
vqrshrn.u16 d25, q4, #7
vqrshrn.u16 d26, q5, #7
vqrshrn.u16 d27, q6, #7
vqrshrn.u16 d28, q7, #7
vqrshrn.u16 d29, q8, #7
b sub_pixel_variance8x8_neon
;--------------------
skip_firstpass_filter
vld1.u8 {d22}, [r0], r1 ;load src data
vld1.u8 {d23}, [r0], r1
vld1.u8 {d24}, [r0], r1
vld1.u8 {d25}, [r0], r1
vld1.u8 {d26}, [r0], r1
vld1.u8 {d27}, [r0], r1
vld1.u8 {d28}, [r0], r1
vld1.u8 {d29}, [r0], r1
vld1.u8 {d30}, [r0], r1
b secondpass_filter
;----------------------
;vp8_variance8x8_neon
sub_pixel_variance8x8_neon
vmov.i8 q8, #0 ;q8 - sum
vmov.i8 q9, #0 ;q9, q10 - sse
vmov.i8 q10, #0
mov r12, #2
sub_pixel_variance8x8_neon_loop
vld1.8 {d0}, [r4], r5 ;load dst data
subs r12, r12, #1
vld1.8 {d1}, [r4], r5
vld1.8 {d2}, [r4], r5
vsubl.u8 q4, d22, d0 ;calculate diff
vld1.8 {d3}, [r4], r5
vsubl.u8 q5, d23, d1
vsubl.u8 q6, d24, d2
vpadal.s16 q8, q4 ;sum
vmlal.s16 q9, d8, d8 ;sse
vmlal.s16 q10, d9, d9
vsubl.u8 q7, d25, d3
vpadal.s16 q8, q5
vmlal.s16 q9, d10, d10
vmlal.s16 q10, d11, d11
vmov q11, q13
vpadal.s16 q8, q6
vmlal.s16 q9, d12, d12
vmlal.s16 q10, d13, d13
vmov q12, q14
vpadal.s16 q8, q7
vmlal.s16 q9, d14, d14
vmlal.s16 q10, d15, d15
bne sub_pixel_variance8x8_neon_loop
vadd.u32 q10, q9, q10 ;accumulate sse
vpaddl.s32 q0, q8 ;accumulate sum
vpaddl.u32 q1, q10
vadd.s64 d0, d0, d1
vadd.u64 d1, d2, d3
vmull.s32 q5, d0, d0
vst1.32 {d1[0]}, [lr] ;store sse
vshr.u32 d10, d10, #6
vsub.u32 d0, d1, d10
vmov.32 r0, d0[0] ;return
vpop {d8-d15}
pop {r4-r5, pc}
ENDP
;-----------------
bilinear_taps_coeff
DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112
END

File diff suppressed because it is too large Load Diff

View File

@ -160,9 +160,6 @@ VP8_COMMON_SRCS-$(HAVE_MEDIA) += common/arm/armv6/vp8_variance_halfpixvar16x16_
VP8_COMMON_SRCS-$(HAVE_NEON_ASM) += common/arm/neon/loopfiltersimpleverticaledge_neon$(ASM)
#VP8_COMMON_SRCS-$(HAVE_NEON_ASM) += common/arm/neon/buildintrapredictorsmby_neon$(ASM)
VP8_COMMON_SRCS-$(HAVE_NEON_ASM) += common/arm/neon/idct_blk_neon.c
VP8_COMMON_SRCS-$(HAVE_NEON_ASM) += common/arm/neon/vp8_subpixelvariance8x8_neon$(ASM)
VP8_COMMON_SRCS-$(HAVE_NEON_ASM) += common/arm/neon/vp8_subpixelvariance16x16_neon$(ASM)
VP8_COMMON_SRCS-$(HAVE_NEON_ASM) += common/arm/neon/vp8_subpixelvariance16x16s_neon$(ASM)
# common (neon intrinsics)
VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/bilinearpredict_neon.c
@ -180,5 +177,6 @@ VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/shortidct4x4llm_neon.c
VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/sixtappredict_neon.c
VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/idct_dequant_0_2x_neon.c
VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/variance_neon.c
VP8_COMMON_SRCS-$(HAVE_NEON) += common/arm/neon/vp8_subpixelvariance_neon.c
$(eval $(call rtcd_h_template,vp8_rtcd,vp8/common/rtcd_defs.pl))