1; 2; Copyright (c) 2013 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 EXPORT |vpx_lpf_horizontal_16_neon| 12 EXPORT |vpx_lpf_horizontal_16_dual_neon| 13 EXPORT |vpx_lpf_vertical_16_neon| 14 EXPORT |vpx_lpf_vertical_16_dual_neon| 15 ARM 16 17 AREA ||.text||, CODE, READONLY, ALIGN=2 18 19; void mb_lpf_horizontal_edge(uint8_t *s, int p, 20; const uint8_t *blimit, 21; const uint8_t *limit, 22; const uint8_t *thresh, 23; int count) 24; r0 uint8_t *s, 25; r1 int p, /* pitch */ 26; r2 const uint8_t *blimit, 27; r3 const uint8_t *limit, 28; sp const uint8_t *thresh, 29; r12 int count 30|mb_lpf_horizontal_edge| PROC 31 push {r4-r8, lr} 32 vpush {d8-d15} 33 ldr r4, [sp, #88] ; load thresh 34 35h_count 36 vld1.8 {d16[]}, [r2] ; load *blimit 37 vld1.8 {d17[]}, [r3] ; load *limit 38 vld1.8 {d18[]}, [r4] ; load *thresh 39 40 sub r8, r0, r1, lsl #3 ; move src pointer down by 8 lines 41 42 vld1.u8 {d0}, [r8@64], r1 ; p7 43 vld1.u8 {d1}, [r8@64], r1 ; p6 44 vld1.u8 {d2}, [r8@64], r1 ; p5 45 vld1.u8 {d3}, [r8@64], r1 ; p4 46 vld1.u8 {d4}, [r8@64], r1 ; p3 47 vld1.u8 {d5}, [r8@64], r1 ; p2 48 vld1.u8 {d6}, [r8@64], r1 ; p1 49 vld1.u8 {d7}, [r8@64], r1 ; p0 50 vld1.u8 {d8}, [r8@64], r1 ; q0 51 vld1.u8 {d9}, [r8@64], r1 ; q1 52 vld1.u8 {d10}, [r8@64], r1 ; q2 53 vld1.u8 {d11}, [r8@64], r1 ; q3 54 vld1.u8 {d12}, [r8@64], r1 ; q4 55 vld1.u8 {d13}, [r8@64], r1 ; q5 56 vld1.u8 {d14}, [r8@64], r1 ; q6 57 vld1.u8 {d15}, [r8@64], r1 ; q7 58 59 bl vpx_wide_mbfilter_neon 60 61 tst r7, #1 62 beq h_mbfilter 63 64 ; flat && mask were not set for any of the channels. Just store the values 65 ; from filter. 66 sub r8, r0, r1, lsl #1 67 68 vst1.u8 {d25}, [r8@64], r1 ; store op1 69 vst1.u8 {d24}, [r8@64], r1 ; store op0 70 vst1.u8 {d23}, [r8@64], r1 ; store oq0 71 vst1.u8 {d26}, [r8@64], r1 ; store oq1 72 73 b h_next 74 75h_mbfilter 76 tst r7, #2 77 beq h_wide_mbfilter 78 79 ; flat2 was not set for any of the channels. Just store the values from 80 ; mbfilter. 81 sub r8, r0, r1, lsl #1 82 sub r8, r8, r1 83 84 vst1.u8 {d18}, [r8@64], r1 ; store op2 85 vst1.u8 {d19}, [r8@64], r1 ; store op1 86 vst1.u8 {d20}, [r8@64], r1 ; store op0 87 vst1.u8 {d21}, [r8@64], r1 ; store oq0 88 vst1.u8 {d22}, [r8@64], r1 ; store oq1 89 vst1.u8 {d23}, [r8@64], r1 ; store oq2 90 91 b h_next 92 93h_wide_mbfilter 94 sub r8, r0, r1, lsl #3 95 add r8, r8, r1 96 97 vst1.u8 {d16}, [r8@64], r1 ; store op6 98 vst1.u8 {d24}, [r8@64], r1 ; store op5 99 vst1.u8 {d25}, [r8@64], r1 ; store op4 100 vst1.u8 {d26}, [r8@64], r1 ; store op3 101 vst1.u8 {d27}, [r8@64], r1 ; store op2 102 vst1.u8 {d18}, [r8@64], r1 ; store op1 103 vst1.u8 {d19}, [r8@64], r1 ; store op0 104 vst1.u8 {d20}, [r8@64], r1 ; store oq0 105 vst1.u8 {d21}, [r8@64], r1 ; store oq1 106 vst1.u8 {d22}, [r8@64], r1 ; store oq2 107 vst1.u8 {d23}, [r8@64], r1 ; store oq3 108 vst1.u8 {d1}, [r8@64], r1 ; store oq4 109 vst1.u8 {d2}, [r8@64], r1 ; store oq5 110 vst1.u8 {d3}, [r8@64], r1 ; store oq6 111 112h_next 113 add r0, r0, #8 114 subs r12, r12, #1 115 bne h_count 116 117 vpop {d8-d15} 118 pop {r4-r8, pc} 119 120 ENDP ; |mb_lpf_horizontal_edge| 121 122; void vpx_lpf_horizontal_16_neon(uint8_t *s, int pitch, 123; const uint8_t *blimit, 124; const uint8_t *limit, 125; const uint8_t *thresh) 126; r0 uint8_t *s, 127; r1 int pitch, 128; r2 const uint8_t *blimit, 129; r3 const uint8_t *limit, 130; sp const uint8_t *thresh 131|vpx_lpf_horizontal_16_neon| PROC 132 mov r12, #1 133 b mb_lpf_horizontal_edge 134 ENDP ; |vpx_lpf_horizontal_16_neon| 135 136; void vpx_lpf_horizontal_16_dual_neon(uint8_t *s, int pitch, 137; const uint8_t *blimit, 138; const uint8_t *limit, 139; const uint8_t *thresh) 140; r0 uint8_t *s, 141; r1 int pitch, 142; r2 const uint8_t *blimit, 143; r3 const uint8_t *limit, 144; sp const uint8_t *thresh 145|vpx_lpf_horizontal_16_dual_neon| PROC 146 mov r12, #2 147 b mb_lpf_horizontal_edge 148 ENDP ; |vpx_lpf_horizontal_16_dual_neon| 149 150; void mb_lpf_vertical_edge_w(uint8_t *s, int p, const uint8_t *blimit, 151; const uint8_t *limit, const uint8_t *thresh, 152; int count) { 153; r0 uint8_t *s, 154; r1 int p, /* pitch */ 155; r2 const uint8_t *blimit, 156; r3 const uint8_t *limit, 157; sp const uint8_t *thresh, 158; r12 int count 159|mb_lpf_vertical_edge_w| PROC 160 push {r4-r8, lr} 161 vpush {d8-d15} 162 ldr r4, [sp, #88] ; load thresh 163 164v_count 165 vld1.8 {d16[]}, [r2] ; load *blimit 166 vld1.8 {d17[]}, [r3] ; load *limit 167 vld1.8 {d18[]}, [r4] ; load *thresh 168 169 sub r8, r0, #8 170 171 vld1.8 {d0}, [r8@64], r1 172 vld1.8 {d8}, [r0@64], r1 173 vld1.8 {d1}, [r8@64], r1 174 vld1.8 {d9}, [r0@64], r1 175 vld1.8 {d2}, [r8@64], r1 176 vld1.8 {d10}, [r0@64], r1 177 vld1.8 {d3}, [r8@64], r1 178 vld1.8 {d11}, [r0@64], r1 179 vld1.8 {d4}, [r8@64], r1 180 vld1.8 {d12}, [r0@64], r1 181 vld1.8 {d5}, [r8@64], r1 182 vld1.8 {d13}, [r0@64], r1 183 vld1.8 {d6}, [r8@64], r1 184 vld1.8 {d14}, [r0@64], r1 185 vld1.8 {d7}, [r8@64], r1 186 vld1.8 {d15}, [r0@64], r1 187 188 sub r0, r0, r1, lsl #3 189 190 vtrn.32 q0, q2 191 vtrn.32 q1, q3 192 vtrn.32 q4, q6 193 vtrn.32 q5, q7 194 195 vtrn.16 q0, q1 196 vtrn.16 q2, q3 197 vtrn.16 q4, q5 198 vtrn.16 q6, q7 199 200 vtrn.8 d0, d1 201 vtrn.8 d2, d3 202 vtrn.8 d4, d5 203 vtrn.8 d6, d7 204 205 vtrn.8 d8, d9 206 vtrn.8 d10, d11 207 vtrn.8 d12, d13 208 vtrn.8 d14, d15 209 210 bl vpx_wide_mbfilter_neon 211 212 tst r7, #1 213 beq v_mbfilter 214 215 ; flat && mask were not set for any of the channels. Just store the values 216 ; from filter. 217 sub r0, #2 218 219 vswp d23, d25 220 221 vst4.8 {d23[0], d24[0], d25[0], d26[0]}, [r0], r1 222 vst4.8 {d23[1], d24[1], d25[1], d26[1]}, [r0], r1 223 vst4.8 {d23[2], d24[2], d25[2], d26[2]}, [r0], r1 224 vst4.8 {d23[3], d24[3], d25[3], d26[3]}, [r0], r1 225 vst4.8 {d23[4], d24[4], d25[4], d26[4]}, [r0], r1 226 vst4.8 {d23[5], d24[5], d25[5], d26[5]}, [r0], r1 227 vst4.8 {d23[6], d24[6], d25[6], d26[6]}, [r0], r1 228 vst4.8 {d23[7], d24[7], d25[7], d26[7]}, [r0], r1 229 add r0, #2 230 231 b v_next 232 233v_mbfilter 234 tst r7, #2 235 beq v_wide_mbfilter 236 237 ; flat2 was not set for any of the channels. Just store the values from 238 ; mbfilter. 239 sub r8, r0, #3 240 241 vst3.8 {d18[0], d19[0], d20[0]}, [r8], r1 242 vst3.8 {d21[0], d22[0], d23[0]}, [r0], r1 243 vst3.8 {d18[1], d19[1], d20[1]}, [r8], r1 244 vst3.8 {d21[1], d22[1], d23[1]}, [r0], r1 245 vst3.8 {d18[2], d19[2], d20[2]}, [r8], r1 246 vst3.8 {d21[2], d22[2], d23[2]}, [r0], r1 247 vst3.8 {d18[3], d19[3], d20[3]}, [r8], r1 248 vst3.8 {d21[3], d22[3], d23[3]}, [r0], r1 249 vst3.8 {d18[4], d19[4], d20[4]}, [r8], r1 250 vst3.8 {d21[4], d22[4], d23[4]}, [r0], r1 251 vst3.8 {d18[5], d19[5], d20[5]}, [r8], r1 252 vst3.8 {d21[5], d22[5], d23[5]}, [r0], r1 253 vst3.8 {d18[6], d19[6], d20[6]}, [r8], r1 254 vst3.8 {d21[6], d22[6], d23[6]}, [r0], r1 255 vst3.8 {d18[7], d19[7], d20[7]}, [r8], r1 256 vst3.8 {d21[7], d22[7], d23[7]}, [r0], r1 257 258 b v_next 259 260v_wide_mbfilter 261 sub r8, r0, #8 262 263 vtrn.32 d0, d26 264 vtrn.32 d16, d27 265 vtrn.32 d24, d18 266 vtrn.32 d25, d19 267 268 vtrn.16 d0, d24 269 vtrn.16 d16, d25 270 vtrn.16 d26, d18 271 vtrn.16 d27, d19 272 273 vtrn.8 d0, d16 274 vtrn.8 d24, d25 275 vtrn.8 d26, d27 276 vtrn.8 d18, d19 277 278 vtrn.32 d20, d1 279 vtrn.32 d21, d2 280 vtrn.32 d22, d3 281 vtrn.32 d23, d15 282 283 vtrn.16 d20, d22 284 vtrn.16 d21, d23 285 vtrn.16 d1, d3 286 vtrn.16 d2, d15 287 288 vtrn.8 d20, d21 289 vtrn.8 d22, d23 290 vtrn.8 d1, d2 291 vtrn.8 d3, d15 292 293 vst1.8 {d0}, [r8@64], r1 294 vst1.8 {d20}, [r0@64], r1 295 vst1.8 {d16}, [r8@64], r1 296 vst1.8 {d21}, [r0@64], r1 297 vst1.8 {d24}, [r8@64], r1 298 vst1.8 {d22}, [r0@64], r1 299 vst1.8 {d25}, [r8@64], r1 300 vst1.8 {d23}, [r0@64], r1 301 vst1.8 {d26}, [r8@64], r1 302 vst1.8 {d1}, [r0@64], r1 303 vst1.8 {d27}, [r8@64], r1 304 vst1.8 {d2}, [r0@64], r1 305 vst1.8 {d18}, [r8@64], r1 306 vst1.8 {d3}, [r0@64], r1 307 vst1.8 {d19}, [r8@64], r1 308 vst1.8 {d15}, [r0@64], r1 309 310v_next 311 subs r12, #1 312 bne v_count 313 314 vpop {d8-d15} 315 pop {r4-r8, pc} 316 317 ENDP ; |mb_lpf_vertical_edge_w| 318 319; void vpx_lpf_vertical_16_neon(uint8_t *s, int p, const uint8_t *blimit, 320; const uint8_t *limit, const uint8_t *thresh) 321; r0 uint8_t *s, 322; r1 int p, /* pitch */ 323; r2 const uint8_t *blimit, 324; r3 const uint8_t *limit, 325; sp const uint8_t *thresh 326|vpx_lpf_vertical_16_neon| PROC 327 mov r12, #1 328 b mb_lpf_vertical_edge_w 329 ENDP ; |vpx_lpf_vertical_16_neon| 330 331; void vpx_lpf_vertical_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit, 332; const uint8_t *limit, 333; const uint8_t *thresh) 334; r0 uint8_t *s, 335; r1 int p, /* pitch */ 336; r2 const uint8_t *blimit, 337; r3 const uint8_t *limit, 338; sp const uint8_t *thresh 339|vpx_lpf_vertical_16_dual_neon| PROC 340 mov r12, #2 341 b mb_lpf_vertical_edge_w 342 ENDP ; |vpx_lpf_vertical_16_dual_neon| 343 344; void vpx_wide_mbfilter_neon(); 345; This is a helper function for the loopfilters. The invidual functions do the 346; necessary load, transpose (if necessary) and store. 347; 348; r0-r3 PRESERVE 349; d16 blimit 350; d17 limit 351; d18 thresh 352; d0 p7 353; d1 p6 354; d2 p5 355; d3 p4 356; d4 p3 357; d5 p2 358; d6 p1 359; d7 p0 360; d8 q0 361; d9 q1 362; d10 q2 363; d11 q3 364; d12 q4 365; d13 q5 366; d14 q6 367; d15 q7 368|vpx_wide_mbfilter_neon| PROC 369 mov r7, #0 370 371 ; filter_mask 372 vabd.u8 d19, d4, d5 ; abs(p3 - p2) 373 vabd.u8 d20, d5, d6 ; abs(p2 - p1) 374 vabd.u8 d21, d6, d7 ; abs(p1 - p0) 375 vabd.u8 d22, d9, d8 ; abs(q1 - q0) 376 vabd.u8 d23, d10, d9 ; abs(q2 - q1) 377 vabd.u8 d24, d11, d10 ; abs(q3 - q2) 378 379 ; only compare the largest value to limit 380 vmax.u8 d19, d19, d20 ; max(abs(p3 - p2), abs(p2 - p1)) 381 vmax.u8 d20, d21, d22 ; max(abs(p1 - p0), abs(q1 - q0)) 382 vmax.u8 d23, d23, d24 ; max(abs(q2 - q1), abs(q3 - q2)) 383 vmax.u8 d19, d19, d20 384 385 vabd.u8 d24, d7, d8 ; abs(p0 - q0) 386 387 vmax.u8 d19, d19, d23 388 389 vabd.u8 d23, d6, d9 ; a = abs(p1 - q1) 390 vqadd.u8 d24, d24, d24 ; b = abs(p0 - q0) * 2 391 392 ; abs () > limit 393 vcge.u8 d19, d17, d19 394 395 ; flatmask4 396 vabd.u8 d25, d7, d5 ; abs(p0 - p2) 397 vabd.u8 d26, d8, d10 ; abs(q0 - q2) 398 vabd.u8 d27, d4, d7 ; abs(p3 - p0) 399 vabd.u8 d28, d11, d8 ; abs(q3 - q0) 400 401 ; only compare the largest value to thresh 402 vmax.u8 d25, d25, d26 ; max(abs(p0 - p2), abs(q0 - q2)) 403 vmax.u8 d26, d27, d28 ; max(abs(p3 - p0), abs(q3 - q0)) 404 vmax.u8 d25, d25, d26 405 vmax.u8 d20, d20, d25 406 407 vshr.u8 d23, d23, #1 ; a = a / 2 408 vqadd.u8 d24, d24, d23 ; a = b + a 409 410 vmov.u8 d30, #1 411 vcge.u8 d24, d16, d24 ; (a > blimit * 2 + limit) * -1 412 413 vcge.u8 d20, d30, d20 ; flat 414 415 vand d19, d19, d24 ; mask 416 417 ; hevmask 418 vcgt.u8 d21, d21, d18 ; (abs(p1 - p0) > thresh)*-1 419 vcgt.u8 d22, d22, d18 ; (abs(q1 - q0) > thresh)*-1 420 vorr d21, d21, d22 ; hev 421 422 vand d16, d20, d19 ; flat && mask 423 vmov r5, r6, d16 424 425 ; flatmask5(1, p7, p6, p5, p4, p0, q0, q4, q5, q6, q7) 426 vabd.u8 d22, d3, d7 ; abs(p4 - p0) 427 vabd.u8 d23, d12, d8 ; abs(q4 - q0) 428 vabd.u8 d24, d7, d2 ; abs(p0 - p5) 429 vabd.u8 d25, d8, d13 ; abs(q0 - q5) 430 vabd.u8 d26, d1, d7 ; abs(p6 - p0) 431 vabd.u8 d27, d14, d8 ; abs(q6 - q0) 432 vabd.u8 d28, d0, d7 ; abs(p7 - p0) 433 vabd.u8 d29, d15, d8 ; abs(q7 - q0) 434 435 ; only compare the largest value to thresh 436 vmax.u8 d22, d22, d23 ; max(abs(p4 - p0), abs(q4 - q0)) 437 vmax.u8 d23, d24, d25 ; max(abs(p0 - p5), abs(q0 - q5)) 438 vmax.u8 d24, d26, d27 ; max(abs(p6 - p0), abs(q6 - q0)) 439 vmax.u8 d25, d28, d29 ; max(abs(p7 - p0), abs(q7 - q0)) 440 441 vmax.u8 d26, d22, d23 442 vmax.u8 d27, d24, d25 443 vmax.u8 d23, d26, d27 444 445 vcge.u8 d18, d30, d23 ; flat2 446 447 vmov.u8 d22, #0x80 448 449 orrs r5, r5, r6 ; Check for 0 450 orreq r7, r7, #1 ; Only do filter branch 451 452 vand d17, d18, d16 ; flat2 && flat && mask 453 vmov r5, r6, d17 454 455 ; mbfilter() function 456 457 ; filter() function 458 ; convert to signed 459 veor d23, d8, d22 ; qs0 460 veor d24, d7, d22 ; ps0 461 veor d25, d6, d22 ; ps1 462 veor d26, d9, d22 ; qs1 463 464 vmov.u8 d27, #3 465 466 vsub.s8 d28, d23, d24 ; ( qs0 - ps0) 467 vqsub.s8 d29, d25, d26 ; filter = clamp(ps1-qs1) 468 vmull.s8 q15, d28, d27 ; 3 * ( qs0 - ps0) 469 vand d29, d29, d21 ; filter &= hev 470 vaddw.s8 q15, q15, d29 ; filter + 3 * (qs0 - ps0) 471 vmov.u8 d29, #4 472 473 ; filter = clamp(filter + 3 * ( qs0 - ps0)) 474 vqmovn.s16 d28, q15 475 476 vand d28, d28, d19 ; filter &= mask 477 478 vqadd.s8 d30, d28, d27 ; filter2 = clamp(filter+3) 479 vqadd.s8 d29, d28, d29 ; filter1 = clamp(filter+4) 480 vshr.s8 d30, d30, #3 ; filter2 >>= 3 481 vshr.s8 d29, d29, #3 ; filter1 >>= 3 482 483 484 vqadd.s8 d24, d24, d30 ; op0 = clamp(ps0 + filter2) 485 vqsub.s8 d23, d23, d29 ; oq0 = clamp(qs0 - filter1) 486 487 ; outer tap adjustments: ++filter1 >> 1 488 vrshr.s8 d29, d29, #1 489 vbic d29, d29, d21 ; filter &= ~hev 490 491 vqadd.s8 d25, d25, d29 ; op1 = clamp(ps1 + filter) 492 vqsub.s8 d26, d26, d29 ; oq1 = clamp(qs1 - filter) 493 494 veor d24, d24, d22 ; *f_op0 = u^0x80 495 veor d23, d23, d22 ; *f_oq0 = u^0x80 496 veor d25, d25, d22 ; *f_op1 = u^0x80 497 veor d26, d26, d22 ; *f_oq1 = u^0x80 498 499 tst r7, #1 500 bxne lr 501 502 orrs r5, r5, r6 ; Check for 0 503 orreq r7, r7, #2 ; Only do mbfilter branch 504 505 ; mbfilter flat && mask branch 506 ; TODO(fgalligan): Can I decrease the cycles shifting to consective d's 507 ; and using vibt on the q's? 508 vmov.u8 d29, #2 509 vaddl.u8 q15, d7, d8 ; op2 = p0 + q0 510 vmlal.u8 q15, d4, d27 ; op2 = p0 + q0 + p3 * 3 511 vmlal.u8 q15, d5, d29 ; op2 = p0 + q0 + p3 * 3 + p2 * 2 512 vaddl.u8 q10, d4, d5 513 vaddw.u8 q15, d6 ; op2=p1 + p0 + q0 + p3 * 3 + p2 *2 514 vaddl.u8 q14, d6, d9 515 vqrshrn.u16 d18, q15, #3 ; r_op2 516 517 vsub.i16 q15, q10 518 vaddl.u8 q10, d4, d6 519 vadd.i16 q15, q14 520 vaddl.u8 q14, d7, d10 521 vqrshrn.u16 d19, q15, #3 ; r_op1 522 523 vsub.i16 q15, q10 524 vadd.i16 q15, q14 525 vaddl.u8 q14, d8, d11 526 vqrshrn.u16 d20, q15, #3 ; r_op0 527 528 vsubw.u8 q15, d4 ; oq0 = op0 - p3 529 vsubw.u8 q15, d7 ; oq0 -= p0 530 vadd.i16 q15, q14 531 vaddl.u8 q14, d9, d11 532 vqrshrn.u16 d21, q15, #3 ; r_oq0 533 534 vsubw.u8 q15, d5 ; oq1 = oq0 - p2 535 vsubw.u8 q15, d8 ; oq1 -= q0 536 vadd.i16 q15, q14 537 vaddl.u8 q14, d10, d11 538 vqrshrn.u16 d22, q15, #3 ; r_oq1 539 540 vsubw.u8 q15, d6 ; oq2 = oq0 - p1 541 vsubw.u8 q15, d9 ; oq2 -= q1 542 vadd.i16 q15, q14 543 vqrshrn.u16 d27, q15, #3 ; r_oq2 544 545 ; Filter does not set op2 or oq2, so use p2 and q2. 546 vbif d18, d5, d16 ; t_op2 |= p2 & ~(flat & mask) 547 vbif d19, d25, d16 ; t_op1 |= f_op1 & ~(flat & mask) 548 vbif d20, d24, d16 ; t_op0 |= f_op0 & ~(flat & mask) 549 vbif d21, d23, d16 ; t_oq0 |= f_oq0 & ~(flat & mask) 550 vbif d22, d26, d16 ; t_oq1 |= f_oq1 & ~(flat & mask) 551 552 vbit d23, d27, d16 ; t_oq2 |= r_oq2 & (flat & mask) 553 vbif d23, d10, d16 ; t_oq2 |= q2 & ~(flat & mask) 554 555 tst r7, #2 556 bxne lr 557 558 ; wide_mbfilter flat2 && flat && mask branch 559 vmov.u8 d16, #7 560 vaddl.u8 q15, d7, d8 ; op6 = p0 + q0 561 vaddl.u8 q12, d2, d3 562 vaddl.u8 q13, d4, d5 563 vaddl.u8 q14, d1, d6 564 vmlal.u8 q15, d0, d16 ; op6 += p7 * 3 565 vadd.i16 q12, q13 566 vadd.i16 q15, q14 567 vaddl.u8 q14, d2, d9 568 vadd.i16 q15, q12 569 vaddl.u8 q12, d0, d1 570 vaddw.u8 q15, d1 571 vaddl.u8 q13, d0, d2 572 vadd.i16 q14, q15, q14 573 vqrshrn.u16 d16, q15, #4 ; w_op6 574 575 vsub.i16 q15, q14, q12 576 vaddl.u8 q14, d3, d10 577 vqrshrn.u16 d24, q15, #4 ; w_op5 578 579 vsub.i16 q15, q13 580 vaddl.u8 q13, d0, d3 581 vadd.i16 q15, q14 582 vaddl.u8 q14, d4, d11 583 vqrshrn.u16 d25, q15, #4 ; w_op4 584 585 vadd.i16 q15, q14 586 vaddl.u8 q14, d0, d4 587 vsub.i16 q15, q13 588 vsub.i16 q14, q15, q14 589 vqrshrn.u16 d26, q15, #4 ; w_op3 590 591 vaddw.u8 q15, q14, d5 ; op2 += p2 592 vaddl.u8 q14, d0, d5 593 vaddw.u8 q15, d12 ; op2 += q4 594 vbif d26, d4, d17 ; op3 |= p3 & ~(f2 & f & m) 595 vqrshrn.u16 d27, q15, #4 ; w_op2 596 597 vsub.i16 q15, q14 598 vaddl.u8 q14, d0, d6 599 vaddw.u8 q15, d6 ; op1 += p1 600 vaddw.u8 q15, d13 ; op1 += q5 601 vbif d27, d18, d17 ; op2 |= t_op2 & ~(f2 & f & m) 602 vqrshrn.u16 d18, q15, #4 ; w_op1 603 604 vsub.i16 q15, q14 605 vaddl.u8 q14, d0, d7 606 vaddw.u8 q15, d7 ; op0 += p0 607 vaddw.u8 q15, d14 ; op0 += q6 608 vbif d18, d19, d17 ; op1 |= t_op1 & ~(f2 & f & m) 609 vqrshrn.u16 d19, q15, #4 ; w_op0 610 611 vsub.i16 q15, q14 612 vaddl.u8 q14, d1, d8 613 vaddw.u8 q15, d8 ; oq0 += q0 614 vaddw.u8 q15, d15 ; oq0 += q7 615 vbif d19, d20, d17 ; op0 |= t_op0 & ~(f2 & f & m) 616 vqrshrn.u16 d20, q15, #4 ; w_oq0 617 618 vsub.i16 q15, q14 619 vaddl.u8 q14, d2, d9 620 vaddw.u8 q15, d9 ; oq1 += q1 621 vaddl.u8 q4, d10, d15 622 vaddw.u8 q15, d15 ; oq1 += q7 623 vbif d20, d21, d17 ; oq0 |= t_oq0 & ~(f2 & f & m) 624 vqrshrn.u16 d21, q15, #4 ; w_oq1 625 626 vsub.i16 q15, q14 627 vaddl.u8 q14, d3, d10 628 vadd.i16 q15, q4 629 vaddl.u8 q4, d11, d15 630 vbif d21, d22, d17 ; oq1 |= t_oq1 & ~(f2 & f & m) 631 vqrshrn.u16 d22, q15, #4 ; w_oq2 632 633 vsub.i16 q15, q14 634 vaddl.u8 q14, d4, d11 635 vadd.i16 q15, q4 636 vaddl.u8 q4, d12, d15 637 vbif d22, d23, d17 ; oq2 |= t_oq2 & ~(f2 & f & m) 638 vqrshrn.u16 d23, q15, #4 ; w_oq3 639 640 vsub.i16 q15, q14 641 vaddl.u8 q14, d5, d12 642 vadd.i16 q15, q4 643 vaddl.u8 q4, d13, d15 644 vbif d16, d1, d17 ; op6 |= p6 & ~(f2 & f & m) 645 vqrshrn.u16 d1, q15, #4 ; w_oq4 646 647 vsub.i16 q15, q14 648 vaddl.u8 q14, d6, d13 649 vadd.i16 q15, q4 650 vaddl.u8 q4, d14, d15 651 vbif d24, d2, d17 ; op5 |= p5 & ~(f2 & f & m) 652 vqrshrn.u16 d2, q15, #4 ; w_oq5 653 654 vsub.i16 q15, q14 655 vbif d25, d3, d17 ; op4 |= p4 & ~(f2 & f & m) 656 vadd.i16 q15, q4 657 vbif d23, d11, d17 ; oq3 |= q3 & ~(f2 & f & m) 658 vqrshrn.u16 d3, q15, #4 ; w_oq6 659 vbif d1, d12, d17 ; oq4 |= q4 & ~(f2 & f & m) 660 vbif d2, d13, d17 ; oq5 |= q5 & ~(f2 & f & m) 661 vbif d3, d14, d17 ; oq6 |= q6 & ~(f2 & f & m) 662 663 bx lr 664 ENDP ; |vpx_wide_mbfilter_neon| 665 666 END 667