Merge "Adds "armvX-none-rvct" targets"
[libvpx.git] / vp8 / encoder / arm / neon / vp8_subpixelvariance16x16_neon.asm
blob5107d8b996039045e9bdcd63bb7800353a460d6a
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|
13 ARM
14 REQUIRE8
15 PRESERVE8
17 AREA ||.text||, CODE, READONLY, ALIGN=2
18 ; r0 unsigned char *src_ptr,
19 ; r1 int src_pixels_per_line,
20 ; r2 int xoffset,
21 ; r3 int yoffset,
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
28 push {r4-r6, lr}
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
48 mov lr, sp
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
57 vdup.8 d1, d31[4]
59 ;First Pass: output_height lines x output_width columns (17x16)
60 vp8e_filt_blk2d_fp16x16_loop_neon
61 pld [r0]
62 pld [r0, r1]
63 pld [r0, r1, lsl #1]
65 vmull.u8 q7, d2, d0 ;(src_ptr[0] * Filter[0])
66 vmull.u8 q8, d3, d0
67 vmull.u8 q9, d5, d0
68 vmull.u8 q10, d6, d0
69 vmull.u8 q11, d8, d0
70 vmull.u8 q12, d9, d0
71 vmull.u8 q13, d11, d0
72 vmull.u8 q14, d12, d0
74 vext.8 d2, d2, d3, #1 ;construct src_ptr[1]
75 vext.8 d5, d5, d6, #1
76 vext.8 d8, d8, d9, #1
77 vext.8 d11, d11, d12, #1
79 vmlal.u8 q7, d2, d1 ;(src_ptr[0] * Filter[1])
80 vmlal.u8 q9, d5, d1
81 vmlal.u8 q11, d8, d1
82 vmlal.u8 q13, d11, d1
84 vext.8 d3, d3, d4, #1
85 vext.8 d6, d6, d7, #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])
90 vmlal.u8 q10, d6, d1
91 vmlal.u8 q12, d9, d1
92 vmlal.u8 q14, d12, d1
94 subs r2, r2, #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])
119 vmull.u8 q10, d3, d0
120 vmull.u8 q11, d5, d0
121 vmull.u8 q12, d6, d0
122 vmull.u8 q13, d8, d0
123 vmull.u8 q14, d9, d0
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])
130 vmlal.u8 q11, d5, d1
131 vmlal.u8 q13, d8, d1
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])
138 vmlal.u8 q12, d6, d1
139 vmlal.u8 q14, d9, d1
141 vmull.u8 q1, d11, d0
142 vmull.u8 q2, d12, d0
143 vmull.u8 q3, d14, d0
144 vmull.u8 q4, d15, d0
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])
150 vmlal.u8 q3, d14, d1
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])
156 vmlal.u8 q4, d15, d1
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]!
173 ;Second pass: 16x16
174 ;secondpass_filter
175 add r3, r12, r3, lsl #3
176 sub lr, lr, #272
178 vld1.u32 {d31}, [r3] ;load second_pass filter
180 sub sp, sp, #256
181 mov r3, sp
183 vld1.u8 {d22, d23}, [lr]! ;load src data
185 vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1)
186 vdup.8 d1, d31[4]
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]!
193 vmull.u8 q2, d23, d0
194 vld1.u8 {d28, d29}, [lr]!
195 vmull.u8 q3, d24, d0
196 vld1.u8 {d30, d31}, [lr]!
198 vmull.u8 q4, d25, d0
199 vmull.u8 q5, d26, d0
200 vmull.u8 q6, d27, d0
201 vmull.u8 q7, d28, d0
202 vmull.u8 q8, d29, d0
204 vmlal.u8 q1, d24, d1 ;(src_ptr[pixel_step] * Filter[1])
205 vmlal.u8 q2, d25, d1
206 vmlal.u8 q3, d26, d1
207 vmlal.u8 q4, d27, d1
208 vmlal.u8 q5, d28, d1
209 vmlal.u8 q6, d29, d1
210 vmlal.u8 q7, d30, d1
211 vmlal.u8 q8, d31, d1
213 subs r12, r12, #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]!
227 vmov q11, q15
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)
239 vdup.8 d1, d31[4]
240 mov r3, sp
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
249 pld [r0]
250 pld [r0, r1]
251 pld [r0, r1, lsl #1]
253 vmull.u8 q7, d2, d0 ;(src_ptr[0] * Filter[0])
254 vmull.u8 q8, d3, d0
255 vmull.u8 q9, d5, d0
256 vmull.u8 q10, d6, d0
257 vmull.u8 q11, d8, d0
258 vmull.u8 q12, d9, d0
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])
268 vmlal.u8 q9, d5, d1
269 vmlal.u8 q11, d8, d1
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])
278 vmlal.u8 q10, d6, d1
279 vmlal.u8 q12, d9, d1
280 vmlal.u8 q14, d12, d1
282 subs r2, r2, #1
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
304 ;Second pass: 16x16
305 ;secondpass_filter
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
311 mov r3, sp
313 vdup.8 d0, d31[0] ;second_pass filter parameters (d0 d1)
314 vdup.8 d1, d31[4]
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
320 vmull.u8 q2, d23, d0
321 vld1.u8 {d28, d29}, [r0], r1
322 vmull.u8 q3, d24, d0
323 vld1.u8 {d30, d31}, [r0], r1
325 vmull.u8 q4, d25, d0
326 vmull.u8 q5, d26, d0
327 vmull.u8 q6, d27, d0
328 vmull.u8 q7, d28, d0
329 vmull.u8 q8, d29, d0
331 vmlal.u8 q1, d24, d1 ;(src_ptr[pixel_step] * Filter[1])
332 vmlal.u8 q2, d25, d1
333 vmlal.u8 q3, d26, d1
334 vmlal.u8 q4, d27, d1
335 vmlal.u8 q5, d28, d1
336 vmlal.u8 q6, d29, d1
337 vmlal.u8 q7, d30, d1
338 vmlal.u8 q8, d31, d1
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
350 subs r12, r12, #1
351 vst1.u8 {d4, d5}, [r3]!
352 vmov q11, q15
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 ;----------------------------
361 ;variance16x16
362 sub_pixel_variance16x16_neon
363 vmov.i8 q8, #0 ;q8 - sum
364 vmov.i8 q9, #0 ;q9, q10 - sse
365 vmov.i8 q10, #0
367 sub r3, r3, #256
368 mov r12, #8
370 sub_pixel_variance16x16_neon_loop
371 vld1.8 {q0}, [r3]! ;Load up source and reference
372 vld1.8 {q2}, [r4], r5
373 vld1.8 {q1}, [r3]!
374 vld1.8 {q3}, [r4], r5
376 vsubl.u8 q11, d0, d4 ;diff
377 vsubl.u8 q12, d1, d5
378 vsubl.u8 q13, d2, d6
379 vsubl.u8 q14, d3, d7
381 vpadal.s16 q8, q11 ;sum
382 vmlal.s16 q9, d22, d22 ;sse
383 vmlal.s16 q10, d23, d23
385 subs r12, r12, #1
387 vpadal.s16 q8, q12
388 vmlal.s16 q9, d24, d24
389 vmlal.s16 q10, d25, d25
390 vpadal.s16 q8, q13
391 vmlal.s16 q9, d26, d26
392 vmlal.s16 q10, d27, d27
393 vpadal.s16 q8, q14
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
402 vpaddl.u32 q1, q10
403 vadd.s64 d0, d0, d1
404 vadd.u64 d1, d2, d3
406 vmull.s32 q5, d0, d0
407 vst1.32 {d1[0]}, [r6] ;store sse
408 vshr.s32 d10, d10, #8
409 vsub.s32 d0, d1, d10
411 add sp, sp, #528
412 vmov.32 r0, d0[0] ;return
414 pop {r4-r6,pc}
416 ENDP
418 ;-----------------
420 _BilinearTaps_coeff_
421 DCD bilinear_taps_coeff
422 bilinear_taps_coeff
423 DCD 128, 0, 112, 16, 96, 32, 80, 48, 64, 64, 48, 80, 32, 96, 16, 112