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_sub_pixel_variance16x16_neon_func|
17 AREA ||.text||
, CODE
, READONLY
, ALIGN=2
18 ; r0 unsigned char *src_ptr,
19 ; r1 int src_pixels_per_line,
22 ; stack(r4) unsigned char *dst_ptr,
23 ; stack(r5) int dst_pixels_per_line,
24 ; stack(r6) unsigned int *sse
25 ;note: most of the code is copied from bilinear_predict16x16_neon and vp8_variance16x16_neon.
27 |vp8_sub_pixel_variance16x16_neon_func|
PROC
30 ldr r12
, _BilinearTaps_coeff_
31 ldr r4
, [sp, #
16] ;load *dst_ptr from stack
32 ldr r5
, [sp, #
20] ;load dst_pixels_per_line from stack
33 ldr r6
, [sp, #
24] ;load *sse from stack
35 cmp r2
, #
0 ;skip first_pass filter if xoffset=0
36 beq secondpass_bfilter16x16_only
38 add r2
, r12
, r2
, lsl #
3 ;calculate filter location
40 cmp r3
, #
0 ;skip second_pass filter if yoffset=0
42 vld1.s32
{d31}, [r2
] ;load first_pass filter
44 beq firstpass_bfilter16x16_only
46 sub sp, sp, #
272 ;reserve space on stack for temporary storage
47 vld1.u8
{d2, d3, d4}, [r0
], r1
;load src data
49 vld1.u8
{d5, d6, d7}, [r0
], r1
51 mov r2
, #
3 ;loop counter
52 vld1.u8
{d8, d9, d10}, [r0
], r1
54 vdup
.8 d0
, d31
[0] ;first_pass filter (d0 d1)
55 vld1.u8
{d11, d12, d13}, [r0
], r1
59 ;First Pass: output_height lines x output_width columns (17x16)
60 vp8e_filt_blk2d_fp16x16_loop_neon
65 vmull.u8 q7
, d2
, d0
;(src_ptr[0] * Filter[0])
74 vext
.8 d2
, d2
, d3
, #
1 ;construct src_ptr[1]
77 vext
.8 d11
, d11
, d12
, #
1
79 vmlal.u8 q7
, d2
, d1
;(src_ptr[0] * Filter[1])
86 vext
.8 d9
, d9
, d10
, #
1
87 vext
.8 d12
, d12
, d13
, #
1
89 vmlal.u8 q8
, d3
, d1
;(src_ptr[0] * Filter[1])
96 vqrshrn.u16 d14
, q7
, #
7 ;shift/round/saturate to u8
97 vqrshrn.u16 d15
, q8
, #
7
98 vqrshrn.u16 d16
, q9
, #
7
99 vqrshrn.u16 d17
, q10
, #
7
100 vqrshrn.u16 d18
, q11
, #
7
101 vqrshrn.u16 d19
, q12
, #
7
102 vqrshrn.u16 d20
, q13
, #
7
104 vld1.u8
{d2, d3, d4}, [r0
], r1
;load src data
105 vqrshrn.u16 d21
, q14
, #
7
106 vld1.u8
{d5, d6, d7}, [r0
], r1
108 vst1.u8
{d14, d15, d16, d17}, [lr
]! ;store result
109 vld1.u8
{d8, d9, d10}, [r0
], r1
110 vst1.u8
{d18, d19, d20, d21}, [lr
]!
111 vld1.u8
{d11, d12, d13}, [r0
], r1
113 bne vp8e_filt_blk2d_fp16x16_loop_neon
115 ;First-pass filtering for rest 5 lines
116 vld1.u8
{d14, d15, d16}, [r0
], r1
118 vmull.u8 q9
, d2
, d0
;(src_ptr[0] * Filter[0])
125 vext
.8 d2
, d2
, d3
, #
1 ;construct src_ptr[1]
126 vext
.8 d5
, d5
, d6
, #
1
127 vext
.8 d8
, d8
, d9
, #
1
129 vmlal.u8 q9
, d2
, d1
;(src_ptr[0] * Filter[1])
133 vext
.8 d3
, d3
, d4
, #
1
134 vext
.8 d6
, d6
, d7
, #
1
135 vext
.8 d9
, d9
, d10
, #
1
137 vmlal.u8 q10
, d3
, d1
;(src_ptr[0] * Filter[1])
146 vext
.8 d11
, d11
, d12
, #
1 ;construct src_ptr[1]
147 vext
.8 d14
, d14
, d15
, #
1
149 vmlal.u8 q1
, d11
, d1
;(src_ptr[0] * Filter[1])
152 vext
.8 d12
, d12
, d13
, #
1
153 vext
.8 d15
, d15
, d16
, #
1
155 vmlal.u8 q2
, d12
, d1
;(src_ptr[0] * Filter[1])
158 vqrshrn.u16 d10
, q9
, #
7 ;shift/round/saturate to u8
159 vqrshrn.u16 d11
, q10
, #
7
160 vqrshrn.u16 d12
, q11
, #
7
161 vqrshrn.u16 d13
, q12
, #
7
162 vqrshrn.u16 d14
, q13
, #
7
163 vqrshrn.u16 d15
, q14
, #
7
164 vqrshrn.u16 d16
, q1
, #
7
165 vqrshrn.u16 d17
, q2
, #
7
166 vqrshrn.u16 d18
, q3
, #
7
167 vqrshrn.u16 d19
, q4
, #
7
169 vst1.u8
{d10, d11, d12, d13}, [lr
]! ;store result
170 vst1.u8
{d14, d15, d16, d17}, [lr
]!
171 vst1.u8
{d18, d19}, [lr
]!
175 add r3
, r12
, r3
, lsl #
3
178 vld1.u32
{d31}, [r3
] ;load second_pass filter
183 vld1.u8
{d22, d23}, [lr
]! ;load src data
185 vdup
.8 d0
, d31
[0] ;second_pass filter parameters (d0 d1)
187 mov r12
, #
4 ;loop counter
189 vp8e_filt_blk2d_sp16x16_loop_neon
190 vld1.u8
{d24, d25}, [lr
]!
191 vmull.u8 q1
, d22
, d0
;(src_ptr[0] * Filter[0])
192 vld1.u8
{d26, d27}, [lr
]!
194 vld1.u8
{d28, d29}, [lr
]!
196 vld1.u8
{d30, d31}, [lr
]!
204 vmlal.u8 q1
, d24
, d1
;(src_ptr[pixel_step] * Filter[1])
215 vqrshrn.u16 d2
, q1
, #
7 ;shift/round/saturate to u8
216 vqrshrn.u16 d3
, q2
, #
7
217 vqrshrn.u16 d4
, q3
, #
7
218 vqrshrn.u16 d5
, q4
, #
7
219 vqrshrn.u16 d6
, q5
, #
7
220 vqrshrn.u16 d7
, q6
, #
7
221 vqrshrn.u16 d8
, q7
, #
7
222 vqrshrn.u16 d9
, q8
, #
7
224 vst1.u8
{d2, d3}, [r3
]! ;store result
225 vst1.u8
{d4, d5}, [r3
]!
226 vst1.u8
{d6, d7}, [r3
]!
228 vst1.u8
{d8, d9}, [r3
]!
230 bne vp8e_filt_blk2d_sp16x16_loop_neon
232 b sub_pixel_variance16x16_neon
234 ;--------------------
235 firstpass_bfilter16x16_only
236 mov r2
, #
4 ;loop counter
237 sub sp, sp, #
528 ;reserve space on stack for temporary storage
238 vdup
.8 d0
, d31
[0] ;first_pass filter (d0 d1)
242 ;First Pass: output_height lines x output_width columns (16x16)
243 vp8e_filt_blk2d_fpo16x16_loop_neon
244 vld1.u8
{d2, d3, d4}, [r0
], r1
;load src data
245 vld1.u8
{d5, d6, d7}, [r0
], r1
246 vld1.u8
{d8, d9, d10}, [r0
], r1
247 vld1.u8
{d11, d12, d13}, [r0
], r1
253 vmull.u8 q7
, d2
, d0
;(src_ptr[0] * Filter[0])
259 vmull.u8 q13
, d11
, d0
260 vmull.u8 q14
, d12
, d0
262 vext
.8 d2
, d2
, d3
, #
1 ;construct src_ptr[1]
263 vext
.8 d5
, d5
, d6
, #
1
264 vext
.8 d8
, d8
, d9
, #
1
265 vext
.8 d11
, d11
, d12
, #
1
267 vmlal.u8 q7
, d2
, d1
;(src_ptr[0] * Filter[1])
270 vmlal.u8 q13
, d11
, d1
272 vext
.8 d3
, d3
, d4
, #
1
273 vext
.8 d6
, d6
, d7
, #
1
274 vext
.8 d9
, d9
, d10
, #
1
275 vext
.8 d12
, d12
, d13
, #
1
277 vmlal.u8 q8
, d3
, d1
;(src_ptr[0] * Filter[1])
280 vmlal.u8 q14
, d12
, d1
284 vqrshrn.u16 d14
, q7
, #
7 ;shift/round/saturate to u8
285 vqrshrn.u16 d15
, q8
, #
7
286 vqrshrn.u16 d16
, q9
, #
7
287 vqrshrn.u16 d17
, q10
, #
7
288 vqrshrn.u16 d18
, q11
, #
7
289 vqrshrn.u16 d19
, q12
, #
7
290 vqrshrn.u16 d20
, q13
, #
7
291 vst1.u8
{d14, d15}, [r3
]! ;store result
292 vqrshrn.u16 d21
, q14
, #
7
294 vst1.u8
{d16, d17}, [r3
]!
295 vst1.u8
{d18, d19}, [r3
]!
296 vst1.u8
{d20, d21}, [r3
]!
298 bne vp8e_filt_blk2d_fpo16x16_loop_neon
300 b sub_pixel_variance16x16_neon
302 ;---------------------
303 secondpass_bfilter16x16_only
306 sub sp, sp, #
528 ;reserve space on stack for temporary storage
307 add r3
, r12
, r3
, lsl #
3
308 mov r12
, #
4 ;loop counter
309 vld1.u32
{d31}, [r3
] ;load second_pass filter
310 vld1.u8
{d22, d23}, [r0
], r1
;load src data
313 vdup
.8 d0
, d31
[0] ;second_pass filter parameters (d0 d1)
316 vp8e_filt_blk2d_spo16x16_loop_neon
317 vld1.u8
{d24, d25}, [r0
], r1
318 vmull.u8 q1
, d22
, d0
;(src_ptr[0] * Filter[0])
319 vld1.u8
{d26, d27}, [r0
], r1
321 vld1.u8
{d28, d29}, [r0
], r1
323 vld1.u8
{d30, d31}, [r0
], r1
331 vmlal.u8 q1
, d24
, d1
;(src_ptr[pixel_step] * Filter[1])
340 vqrshrn.u16 d2
, q1
, #
7 ;shift/round/saturate to u8
341 vqrshrn.u16 d3
, q2
, #
7
342 vqrshrn.u16 d4
, q3
, #
7
343 vqrshrn.u16 d5
, q4
, #
7
344 vqrshrn.u16 d6
, q5
, #
7
345 vqrshrn.u16 d7
, q6
, #
7
346 vqrshrn.u16 d8
, q7
, #
7
347 vqrshrn.u16 d9
, q8
, #
7
349 vst1.u8
{d2, d3}, [r3
]! ;store result
351 vst1.u8
{d4, d5}, [r3
]!
353 vst1.u8
{d6, d7}, [r3
]!
354 vst1.u8
{d8, d9}, [r3
]!
356 bne vp8e_filt_blk2d_spo16x16_loop_neon
358 b sub_pixel_variance16x16_neon
360 ;----------------------------
362 sub_pixel_variance16x16_neon
363 vmov.i8 q8
, #
0 ;q8 - sum
364 vmov.i8 q9
, #
0 ;q9, q10 - sse
370 sub_pixel_variance16x16_neon_loop
371 vld1.8
{q0}, [r3
]! ;Load up source and reference
372 vld1.8
{q2}, [r4
], r5
374 vld1.8
{q3}, [r4
], r5
376 vsubl.u8 q11
, d0
, d4
;diff
381 vpadal.s16 q8
, q11
;sum
382 vmlal.s16 q9
, d22
, d22
;sse
383 vmlal.s16 q10
, d23
, d23
388 vmlal.s16 q9
, d24
, d24
389 vmlal.s16 q10
, d25
, d25
391 vmlal.s16 q9
, d26
, d26
392 vmlal.s16 q10
, d27
, d27
394 vmlal.s16 q9
, d28
, d28
395 vmlal.s16 q10
, d29
, d29
397 bne sub_pixel_variance16x16_neon_loop
399 vadd.u32 q10
, q9
, q10
;accumulate sse
400 vpaddl.s32 q0
, q8
;accumulate sum
407 vst1.32
{d1[0]}, [r6
] ;store sse
408 vshr.s32 d10
, d10
, #
8
412 vmov
.32 r0
, d0
[0] ;return
421 DCD bilinear_taps_coeff
423 DCD
128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112