1 ; 2 ; Copyright (c) 2010 The WebM project authors. All Rights Reserved. 3 ; 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. 9 ; 10 11 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| 16 ARM 17 REQUIRE8 18 PRESERVE8 19 20 AREA ||.text||, CODE, READONLY, ALIGN=2 21 22 ;================================================ 23 ;unsigned int vp8_variance_halfpixvar16x16_h_neon 24 ;( 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 29 ; unsigned int *sse 30 ;); 31 ;================================================ 32 |vp8_variance_halfpixvar16x16_h_neon| PROC 33 push {lr} 34 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 39 vmov.i8 q10, #0 40 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 50 51 ;pld [r0] 52 ;pld [r0, r1] 53 ;pld [r0, r1, lsl #1] 54 55 vext.8 q1, q0, q1, #1 ;construct src_ptr[1] 56 vext.8 q3, q2, q3, #1 57 vext.8 q5, q4, q5, #1 58 vext.8 q7, q6, q7, #1 59 60 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1 61 vld1.8 {q14}, [r2], r3 62 vrhadd.u8 q1, q2, q3 63 vrhadd.u8 q2, q4, q5 64 vrhadd.u8 q3, q6, q7 65 66 vsubl.u8 q4, d0, d22 ;diff 67 vsubl.u8 q5, d1, d23 68 vsubl.u8 q6, d2, d24 69 vsubl.u8 q7, d3, d25 70 vsubl.u8 q0, d4, d26 71 vsubl.u8 q1, d5, d27 72 vsubl.u8 q2, d6, d28 73 vsubl.u8 q3, d7, d29 74 75 vpadal.s16 q8, q4 ;sum 76 vmlal.s16 q9, d8, d8 ;sse 77 vmlal.s16 q10, d9, d9 78 79 subs r12, r12, #1 80 81 vpadal.s16 q8, q5 82 vmlal.s16 q9, d10, d10 83 vmlal.s16 q10, d11, d11 84 vpadal.s16 q8, q6 85 vmlal.s16 q9, d12, d12 86 vmlal.s16 q10, d13, d13 87 vpadal.s16 q8, q7 88 vmlal.s16 q9, d14, d14 89 vmlal.s16 q10, d15, d15 90 91 vpadal.s16 q8, q0 ;sum 92 vmlal.s16 q9, d0, d0 ;sse 93 vmlal.s16 q10, d1, d1 94 vpadal.s16 q8, q1 95 vmlal.s16 q9, d2, d2 96 vmlal.s16 q10, d3, d3 97 vpadal.s16 q8, q2 98 vmlal.s16 q9, d4, d4 99 vmlal.s16 q10, d5, d5 100 vpadal.s16 q8, q3 101 vmlal.s16 q9, d6, d6 102 vmlal.s16 q10, d7, d7 103 104 bne vp8_filt_fpo16x16s_4_0_loop_neon 105 106 vadd.u32 q10, q9, q10 ;accumulate sse 107 vpaddl.s32 q0, q8 ;accumulate sum 108 109 vpaddl.u32 q1, q10 110 vadd.s64 d0, d0, d1 111 vadd.u64 d1, d2, d3 112 113 vmull.s32 q5, d0, d0 114 vst1.32 {d1[0]}, [lr] ;store sse 115 vshr.s32 d10, d10, #8 116 vsub.s32 d0, d1, d10 117 118 vmov.32 r0, d0[0] ;return 119 pop {pc} 120 ENDP 121 122 ;================================================ 123 ;unsigned int vp8_variance_halfpixvar16x16_v_neon 124 ;( 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 129 ; unsigned int *sse 130 ;); 131 ;================================================ 132 |vp8_variance_halfpixvar16x16_v_neon| PROC 133 push {lr} 134 135 mov r12, #4 ;loop counter 136 137 vld1.u8 {q0}, [r0], r1 ;load src data 138 ldr lr, [sp, #4] ;load *sse from stack 139 140 vmov.i8 q8, #0 ;q8 - sum 141 vmov.i8 q9, #0 ;q9, q10 - sse 142 vmov.i8 q10, #0 143 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 152 153 vrhadd.u8 q0, q0, q2 154 vld1.8 {q7}, [r2], r3 155 vrhadd.u8 q2, q2, q4 156 vrhadd.u8 q4, q4, q6 157 vrhadd.u8 q6, q6, q15 158 159 vsubl.u8 q11, d0, d2 ;diff 160 vsubl.u8 q12, d1, d3 161 vsubl.u8 q13, d4, d6 162 vsubl.u8 q14, d5, d7 163 vsubl.u8 q0, d8, d10 164 vsubl.u8 q1, d9, d11 165 vsubl.u8 q2, d12, d14 166 vsubl.u8 q3, d13, d15 167 168 vpadal.s16 q8, q11 ;sum 169 vmlal.s16 q9, d22, d22 ;sse 170 vmlal.s16 q10, d23, d23 171 172 subs r12, r12, #1 173 174 vpadal.s16 q8, q12 175 vmlal.s16 q9, d24, d24 176 vmlal.s16 q10, d25, d25 177 vpadal.s16 q8, q13 178 vmlal.s16 q9, d26, d26 179 vmlal.s16 q10, d27, d27 180 vpadal.s16 q8, q14 181 vmlal.s16 q9, d28, d28 182 vmlal.s16 q10, d29, d29 183 184 vpadal.s16 q8, q0 ;sum 185 vmlal.s16 q9, d0, d0 ;sse 186 vmlal.s16 q10, d1, d1 187 vpadal.s16 q8, q1 188 vmlal.s16 q9, d2, d2 189 vmlal.s16 q10, d3, d3 190 vpadal.s16 q8, q2 191 vmlal.s16 q9, d4, d4 192 vmlal.s16 q10, d5, d5 193 194 vmov q0, q15 195 196 vpadal.s16 q8, q3 197 vmlal.s16 q9, d6, d6 198 vmlal.s16 q10, d7, d7 199 200 bne vp8_filt_spo16x16s_0_4_loop_neon 201 202 vadd.u32 q10, q9, q10 ;accumulate sse 203 vpaddl.s32 q0, q8 ;accumulate sum 204 205 vpaddl.u32 q1, q10 206 vadd.s64 d0, d0, d1 207 vadd.u64 d1, d2, d3 208 209 vmull.s32 q5, d0, d0 210 vst1.32 {d1[0]}, [lr] ;store sse 211 vshr.s32 d10, d10, #8 212 vsub.s32 d0, d1, d10 213 214 vmov.32 r0, d0[0] ;return 215 pop {pc} 216 ENDP 217 218 ;================================================ 219 ;unsigned int vp8_variance_halfpixvar16x16_hv_neon 220 ;( 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 225 ; unsigned int *sse 226 ;); 227 ;================================================ 228 |vp8_variance_halfpixvar16x16_hv_neon| PROC 229 push {lr} 230 231 vld1.u8 {d0, d1, d2, d3}, [r0], r1 ;load src data 232 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] 236 237 vmov.i8 q14, #0 ;q9, q10 - sse 238 vmov.i8 q15, #0 239 240 mov r12, #4 ;loop counter 241 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1 242 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 249 250 ;pld [r0] 251 ;pld [r0, r1] 252 ;pld [r0, r1, lsl #1] 253 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 258 259 vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1 260 vrhadd.u8 q2, q4, q5 261 vrhadd.u8 q3, q6, q7 262 vrhadd.u8 q4, q8, q9 263 264 vld1.8 {q5}, [r2], r3 265 vrhadd.u8 q0, q0, q1 266 vld1.8 {q6}, [r2], r3 267 vrhadd.u8 q1, q1, q2 268 vld1.8 {q7}, [r2], r3 269 vrhadd.u8 q2, q2, q3 270 vld1.8 {q8}, [r2], r3 271 vrhadd.u8 q3, q3, q4 272 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 277 278 vsubl.u8 q0, d4, d14 ;diff 279 vsubl.u8 q1, d5, d15 280 vsubl.u8 q5, d6, d16 281 vsubl.u8 q6, d7, d17 282 283 vpadal.s16 q13, q9 ;sum 284 vmlal.s16 q14, d18, d18 ;sse 285 vmlal.s16 q15, d19, d19 286 287 vpadal.s16 q13, q10 ;sum 288 vmlal.s16 q14, d20, d20 ;sse 289 vmlal.s16 q15, d21, d21 290 291 vpadal.s16 q13, q11 ;sum 292 vmlal.s16 q14, d22, d22 ;sse 293 vmlal.s16 q15, d23, d23 294 295 vpadal.s16 q13, q12 ;sum 296 vmlal.s16 q14, d24, d24 ;sse 297 vmlal.s16 q15, d25, d25 298 299 subs r12, r12, #1 300 301 vpadal.s16 q13, q0 ;sum 302 vmlal.s16 q14, d0, d0 ;sse 303 vmlal.s16 q15, d1, d1 304 305 vpadal.s16 q13, q1 ;sum 306 vmlal.s16 q14, d2, d2 ;sse 307 vmlal.s16 q15, d3, d3 308 309 vpadal.s16 q13, q5 ;sum 310 vmlal.s16 q14, d10, d10 ;sse 311 vmlal.s16 q15, d11, d11 312 313 vmov q0, q4 314 315 vpadal.s16 q13, q6 ;sum 316 vmlal.s16 q14, d12, d12 ;sse 317 vmlal.s16 q15, d13, d13 318 319 bne vp8_filt16x16s_4_4_loop_neon 320 321 vadd.u32 q15, q14, q15 ;accumulate sse 322 vpaddl.s32 q0, q13 ;accumulate sum 323 324 vpaddl.u32 q1, q15 325 vadd.s64 d0, d0, d1 326 vadd.u64 d1, d2, d3 327 328 vmull.s32 q5, d0, d0 329 vst1.32 {d1[0]}, [lr] ;store sse 330 vshr.s32 d10, d10, #8 331 vsub.s32 d0, d1, d10 332 333 vmov.32 r0, d0[0] ;return 334 pop {pc} 335 ENDP 336 337 ;============================== 338 ; r0 unsigned char *src_ptr, 339 ; r1 int src_pixels_per_line, 340 ; r2 int xoffset, 341 ; r3 int yoffset, 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. 349 350 |vp8_sub_pixel_variance16x16s_neon| PROC 351 push {r4, lr} 352 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 356 357 cmp r2, #0 ;skip first_pass filter if xoffset=0 358 beq secondpass_bfilter16x16s_only 359 360 cmp r3, #0 ;skip second_pass filter if yoffset=0 361 beq firstpass_bfilter16x16s_only 362 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] 366 mov r3, sp 367 mov r2, #4 ;loop counter 368 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1 369 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 376 377 ;pld [r0] 378 ;pld [r0, r1] 379 ;pld [r0, r1, lsl #1] 380 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 385 386 vrhadd.u8 q1, q2, q3 ;(src_ptr[0]+src_ptr[1])/round/shift right 1 387 vrhadd.u8 q2, q4, q5 388 vrhadd.u8 q3, q6, q7 389 vrhadd.u8 q4, q8, q9 390 391 vrhadd.u8 q0, q0, q1 392 vrhadd.u8 q1, q1, q2 393 vrhadd.u8 q2, q2, q3 394 vrhadd.u8 q3, q3, q4 395 396 subs r2, r2, #1 397 vst1.u8 {d0, d1 ,d2, d3}, [r3]! ;store result 398 vmov q0, q4 399 vst1.u8 {d4, d5, d6, d7}, [r3]! 400 401 bne vp8e_filt_blk2d_fp16x16s_loop_neon 402 403 b sub_pixel_variance16x16s_neon 404 405 ;-------------------- 406 firstpass_bfilter16x16s_only 407 mov r2, #2 ;loop counter 408 sub sp, sp, #256 ;reserve space on stack for temporary storage 409 mov r3, sp 410 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 417 418 ;pld [r0] 419 ;pld [r0, r1] 420 ;pld [r0, r1, lsl #1] 421 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 434 435 vrhadd.u8 q0, q0, q1 ;(src_ptr[0]+src_ptr[1])/round/shift right 1 436 vrhadd.u8 q1, q2, q3 437 vrhadd.u8 q2, q4, q5 438 vrhadd.u8 q3, q6, q7 439 vrhadd.u8 q4, q8, q9 440 vrhadd.u8 q5, q10, q11 441 vrhadd.u8 q6, q12, q13 442 vrhadd.u8 q7, q14, q15 443 444 subs r2, r2, #1 445 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]! 450 451 bne vp8e_filt_blk2d_fpo16x16s_loop_neon 452 453 b sub_pixel_variance16x16s_neon 454 455 ;--------------------- 456 secondpass_bfilter16x16s_only 457 sub sp, sp, #256 ;reserve space on stack for temporary storage 458 459 mov r2, #2 ;loop counter 460 vld1.u8 {d0, d1}, [r0], r1 ;load src data 461 mov r3, sp 462 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 468 469 vrhadd.u8 q0, q0, q1 470 vld1.u8 {d10, d11}, [r0], r1 471 vrhadd.u8 q1, q1, q2 472 vld1.u8 {d12, d13}, [r0], r1 473 vrhadd.u8 q2, q2, q3 474 vld1.u8 {d14, d15}, [r0], r1 475 vrhadd.u8 q3, q3, q4 476 vld1.u8 {d16, d17}, [r0], r1 477 vrhadd.u8 q4, q4, q5 478 vrhadd.u8 q5, q5, q6 479 vrhadd.u8 q6, q6, q7 480 vrhadd.u8 q7, q7, q8 481 482 subs r2, r2, #1 483 484 vst1.u8 {d0, d1, d2, d3}, [r3]! ;store result 485 vmov q0, q8 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]! 489 490 bne vp8e_filt_blk2d_spo16x16s_loop_neon 491 492 b sub_pixel_variance16x16s_neon 493 494 ;---------------------------- 495 ;variance16x16 496 sub_pixel_variance16x16s_neon 497 vmov.i8 q8, #0 ;q8 - sum 498 vmov.i8 q9, #0 ;q9, q10 - sse 499 vmov.i8 q10, #0 500 501 sub r3, r3, #256 502 mov r2, #4 503 504 sub_pixel_variance16x16s_neon_loop 505 vld1.8 {q0}, [r3]! ;Load up source and reference 506 vld1.8 {q1}, [r4], r12 507 vld1.8 {q2}, [r3]! 508 vld1.8 {q3}, [r4], r12 509 vld1.8 {q4}, [r3]! 510 vld1.8 {q5}, [r4], r12 511 vld1.8 {q6}, [r3]! 512 vld1.8 {q7}, [r4], r12 513 514 vsubl.u8 q11, d0, d2 ;diff 515 vsubl.u8 q12, d1, d3 516 vsubl.u8 q13, d4, d6 517 vsubl.u8 q14, d5, d7 518 vsubl.u8 q0, d8, d10 519 vsubl.u8 q1, d9, d11 520 vsubl.u8 q2, d12, d14 521 vsubl.u8 q3, d13, d15 522 523 vpadal.s16 q8, q11 ;sum 524 vmlal.s16 q9, d22, d22 ;sse 525 vmlal.s16 q10, d23, d23 526 527 subs r2, r2, #1 528 529 vpadal.s16 q8, q12 530 vmlal.s16 q9, d24, d24 531 vmlal.s16 q10, d25, d25 532 vpadal.s16 q8, q13 533 vmlal.s16 q9, d26, d26 534 vmlal.s16 q10, d27, d27 535 vpadal.s16 q8, q14 536 vmlal.s16 q9, d28, d28 537 vmlal.s16 q10, d29, d29 538 539 vpadal.s16 q8, q0 ;sum 540 vmlal.s16 q9, d0, d0 ;sse 541 vmlal.s16 q10, d1, d1 542 vpadal.s16 q8, q1 543 vmlal.s16 q9, d2, d2 544 vmlal.s16 q10, d3, d3 545 vpadal.s16 q8, q2 546 vmlal.s16 q9, d4, d4 547 vmlal.s16 q10, d5, d5 548 vpadal.s16 q8, q3 549 vmlal.s16 q9, d6, d6 550 vmlal.s16 q10, d7, d7 551 552 bne sub_pixel_variance16x16s_neon_loop 553 554 vadd.u32 q10, q9, q10 ;accumulate sse 555 vpaddl.s32 q0, q8 ;accumulate sum 556 557 vpaddl.u32 q1, q10 558 vadd.s64 d0, d0, d1 559 vadd.u64 d1, d2, d3 560 561 vmull.s32 q5, d0, d0 562 vst1.32 {d1[0]}, [lr] ;store sse 563 vshr.s32 d10, d10, #8 564 vsub.s32 d0, d1, d10 565 566 add sp, sp, #256 567 vmov.32 r0, d0[0] ;return 568 569 pop {r4, pc} 570 ENDP 571 572 END 573