1/* 2 * Copyright © 2018, VideoLAN and dav1d authors 3 * Copyright © 2018, Janne Grunau 4 * Copyright © 2020, Martin Storsjo 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, this 11 * list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include "src/arm/asm.S" 30#include "util.S" 31 32#define PREP_BIAS 8192 33 34.macro avg d0, d00, d01, d1, d10, d11 35 vld1.16 {q0, q1}, [r2, :128]! 36 vld1.16 {q2, q3}, [r3, :128]! 37 vqadd.s16 q0, q0, q2 38 vqadd.s16 q1, q1, q3 39 vmax.s16 q0, q0, q12 // -2*PREP_BIAS - 1 << intermediate_bits 40 vmax.s16 q1, q1, q12 // -2*PREP_BIAS - 1 << intermediate_bits 41 vqsub.s16 q0, q0, q12 // -2*PREP_BIAS - 1 << intermediate_bits 42 vqsub.s16 q1, q1, q12 // -2*PREP_BIAS - 1 << intermediate_bits 43 vshl.s16 \d0, q0, q13 // -(intermediate_bits+1) 44 vshl.s16 \d1, q1, q13 // -(intermediate_bits+1) 45.endm 46 47.macro w_avg d0, d00, d01, d1, d10, d11 48 vld1.16 {q0, q1}, [r2, :128]! 49 vld1.16 {q2, q3}, [r3, :128]! 50 // This difference requires a 17 bit range, and all bits are 51 // significant for the following multiplication. 52 vsubl.s16 \d0, d4, d0 53 vsubl.s16 q0, d5, d1 54 vsubl.s16 \d1, d6, d2 55 vsubl.s16 q1, d7, d3 56 vmul.s32 \d0, \d0, q4 57 vmul.s32 q0, q0, q4 58 vmul.s32 \d1, \d1, q4 59 vmul.s32 q1, q1, q4 60 vshr.s32 \d0, \d0, #4 61 vshr.s32 q0, q0, #4 62 vshr.s32 \d1, \d1, #4 63 vshr.s32 q1, q1, #4 64 vaddw.s16 \d0, \d0, d4 65 vaddw.s16 q0, q0, d5 66 vaddw.s16 \d1, \d1, d6 67 vaddw.s16 q1, q1, d7 68 vmovn.i32 \d00, \d0 69 vmovn.i32 \d01, q0 70 vmovn.i32 \d10, \d1 71 vmovn.i32 \d11, q1 72 vrshl.s16 \d0, \d0, q13 // -intermediate_bits 73 vrshl.s16 \d1, \d1, q13 // -intermediate_bits 74 vadd.s16 \d0, \d0, q12 // PREP_BIAS >> intermediate_bits 75 vadd.s16 \d1, \d1, q12 // PREP_BIAS >> intermediate_bits 76 vmin.s16 \d0, \d0, q15 // bitdepth_max 77 vmin.s16 \d1, \d1, q15 // bitdepth_max 78 vmax.s16 \d0, \d0, q14 // 0 79 vmax.s16 \d1, \d1, q14 // 0 80.endm 81 82.macro mask d0, d00, d01, d1, d10, d11 83 vld1.8 {q7}, [r6, :128]! 84 vld1.16 {q0, q1}, [r2, :128]! 85 vneg.s8 q7, q7 86 vld1.16 {q2, q3}, [r3, :128]! 87 vmovl.s8 q6, d14 88 vmovl.s8 q7, d15 89 vmovl.s16 q4, d12 90 vmovl.s16 q5, d13 91 vmovl.s16 q6, d14 92 vmovl.s16 q7, d15 93 vsubl.s16 \d0, d4, d0 94 vsubl.s16 q0, d5, d1 95 vsubl.s16 \d1, d6, d2 96 vsubl.s16 q1, d7, d3 97 vmul.s32 \d0, \d0, q4 98 vmul.s32 q0, q0, q5 99 vmul.s32 \d1, \d1, q6 100 vmul.s32 q1, q1, q7 101 vshr.s32 \d0, \d0, #6 102 vshr.s32 q0, q0, #6 103 vshr.s32 \d1, \d1, #6 104 vshr.s32 q1, q1, #6 105 vaddw.s16 \d0, \d0, d4 106 vaddw.s16 q0, q0, d5 107 vaddw.s16 \d1, \d1, d6 108 vaddw.s16 q1, q1, d7 109 vmovn.i32 \d00, \d0 110 vmovn.i32 \d01, q0 111 vmovn.i32 \d10, \d1 112 vmovn.i32 \d11, q1 113 vrshl.s16 \d0, \d0, q13 // -intermediate_bits 114 vrshl.s16 \d1, \d1, q13 // -intermediate_bits 115 vadd.s16 \d0, \d0, q12 // PREP_BIAS >> intermediate_bits 116 vadd.s16 \d1, \d1, q12 // PREP_BIAS >> intermediate_bits 117 vmin.s16 \d0, \d0, q15 // bitdepth_max 118 vmin.s16 \d1, \d1, q15 // bitdepth_max 119 vmax.s16 \d0, \d0, q14 // 0 120 vmax.s16 \d1, \d1, q14 // 0 121.endm 122 123.macro bidir_fn type, bdmax 124function \type\()_16bpc_neon, export=1 125 push {r4-r7,lr} 126 ldr r4, [sp, #20] 127 ldr r5, [sp, #24] 128 ldr r6, [sp, #28] 129 clz r4, r4 130.ifnc \type, avg 131 ldr r7, [sp, #32] 132 vmov.i16 q14, #0 133 vdup.16 q15, r7 // bitdepth_max 134.endif 135.ifc \type, w_avg 136 vpush {q4} 137.endif 138.ifc \type, mask 139 vpush {q4-q7} 140.endif 141 clz r7, \bdmax 142 sub r7, r7, #18 // intermediate_bits = clz(bitdepth_max) - 18 143.ifc \type, avg 144 mov lr, #1 145 movw r12, #2*PREP_BIAS 146 lsl lr, lr, r7 // 1 << intermediate_bits 147 neg r12, r12 // -2*PREP_BIAS 148 add r7, r7, #1 149 sub r12, r12, lr // -2*PREP_BIAS - 1 << intermediate_bits 150 neg r7, r7 // -(intermediate_bits+1) 151 vdup.16 q12, r12 // -2*PREP_BIAS - 1 << intermediate_bits 152 vdup.16 q13, r7 // -(intermediate_bits+1) 153.else 154 mov r12, #PREP_BIAS 155 lsr r12, r12, r7 // PREP_BIAS >> intermediate_bits 156 neg r7, r7 // -intermediate_bits 157 vdup.16 q12, r12 // PREP_BIAS >> intermediate_bits 158 vdup.16 q13, r7 // -intermediate_bits 159.endif 160.ifc \type, w_avg 161 vdup.32 q4, r6 162 vneg.s32 q4, q4 163.endif 164 adr r7, L(\type\()_tbl) 165 sub r4, r4, #24 166 \type q8, d16, d17, q9, d18, d19 167 ldr r4, [r7, r4, lsl #2] 168 add r7, r7, r4 169 bx r7 170 171 .align 2 172L(\type\()_tbl): 173 .word 1280f - L(\type\()_tbl) + CONFIG_THUMB 174 .word 640f - L(\type\()_tbl) + CONFIG_THUMB 175 .word 320f - L(\type\()_tbl) + CONFIG_THUMB 176 .word 160f - L(\type\()_tbl) + CONFIG_THUMB 177 .word 80f - L(\type\()_tbl) + CONFIG_THUMB 178 .word 40f - L(\type\()_tbl) + CONFIG_THUMB 179 18040: 181 add r7, r0, r1 182 lsl r1, r1, #1 1834: 184 subs r5, r5, #4 185 vst1.16 {d16}, [r0, :64], r1 186 vst1.16 {d17}, [r7, :64], r1 187 vst1.16 {d18}, [r0, :64], r1 188 vst1.16 {d19}, [r7, :64], r1 189 ble 0f 190 \type q8, d16, d17, q9, d18, d19 191 b 4b 19280: 193 add r7, r0, r1 194 lsl r1, r1, #1 1958: 196 vst1.16 {q8}, [r0, :128], r1 197 subs r5, r5, #2 198 vst1.16 {q9}, [r7, :128], r1 199 ble 0f 200 \type q8, d16, d17, q9, d18, d19 201 b 8b 202160: 20316: 204 \type q10, d20, d21, q11, d22, d23 205 vst1.16 {q8, q9}, [r0, :128], r1 206 subs r5, r5, #2 207 vst1.16 {q10, q11}, [r0, :128], r1 208 ble 0f 209 \type q8, d16, d17, q9, d18, d19 210 b 16b 211320: 212 add r7, r0, #32 21332: 214 \type q10, d20, d21, q11, d22, d23 215 vst1.16 {q8, q9}, [r0, :128], r1 216 subs r5, r5, #1 217 vst1.16 {q10, q11}, [r7, :128], r1 218 ble 0f 219 \type q8, d16, d17, q9, d18, d19 220 b 32b 221640: 222 add r7, r0, #32 223 mov r12, #64 224 sub r1, r1, #64 22564: 226 \type q10, d20, d21, q11, d22, d23 227 vst1.16 {q8, q9}, [r0, :128], r12 228 \type q8, d16, d17, q9, d18, d19 229 vst1.16 {q10, q11}, [r7, :128], r12 230 \type q10, d20, d21, q11, d22, d23 231 vst1.16 {q8, q9}, [r0, :128], r1 232 subs r5, r5, #1 233 vst1.16 {q10, q11}, [r7, :128], r1 234 ble 0f 235 \type q8, d16, d17, q9, d18, d19 236 b 64b 2371280: 238 add r7, r0, #32 239 mov r12, #64 240 sub r1, r1, #192 241128: 242 \type q10, d20, d21, q11, d22, d23 243 vst1.16 {q8, q9}, [r0, :128], r12 244 \type q8, d16, d17, q9, d18, d19 245 vst1.16 {q10, q11}, [r7, :128], r12 246 \type q10, d20, d21, q11, d22, d23 247 vst1.16 {q8, q9}, [r0, :128], r12 248 \type q8, d16, d17, q9, d18, d19 249 vst1.16 {q10, q11}, [r7, :128], r12 250 \type q10, d20, d21, q11, d22, d23 251 vst1.16 {q8, q9}, [r0, :128], r12 252 \type q8, d16, d17, q9, d18, d19 253 vst1.16 {q10, q11}, [r7, :128], r12 254 \type q10, d20, d21, q11, d22, d23 255 vst1.16 {q8, q9}, [r0, :128], r1 256 subs r5, r5, #1 257 vst1.16 {q10, q11}, [r7, :128], r1 258 ble 0f 259 \type q8, d16, d17, q9, d18, d19 260 b 128b 2610: 262.ifc \type, mask 263 vpop {q4-q7} 264.endif 265.ifc \type, w_avg 266 vpop {q4} 267.endif 268 pop {r4-r7,pc} 269endfunc 270.endm 271 272bidir_fn avg, r6 273bidir_fn w_avg, r7 274bidir_fn mask, r7 275 276 277// This has got the same signature as the put_8tap functions, 278// and assumes that r9 is set to (clz(w)-24). 279function put_neon 280 adr r10, L(put_tbl) 281 ldr r9, [r10, r9, lsl #2] 282 add r10, r10, r9 283 bx r10 284 285 .align 2 286L(put_tbl): 287 .word 1280f - L(put_tbl) + CONFIG_THUMB 288 .word 640f - L(put_tbl) + CONFIG_THUMB 289 .word 320f - L(put_tbl) + CONFIG_THUMB 290 .word 16f - L(put_tbl) + CONFIG_THUMB 291 .word 80f - L(put_tbl) + CONFIG_THUMB 292 .word 4f - L(put_tbl) + CONFIG_THUMB 293 .word 2f - L(put_tbl) + CONFIG_THUMB 294 2952: 296 vld1.32 {d0[]}, [r2], r3 297 vld1.32 {d1[]}, [r2], r3 298 subs r5, r5, #2 299 vst1.32 {d0[0]}, [r0, :32], r1 300 vst1.32 {d1[1]}, [r0, :32], r1 301 bgt 2b 302 pop {r4-r11,pc} 3034: 304 vld1.16 {d0}, [r2], r3 305 vld1.16 {d1}, [r2], r3 306 subs r5, r5, #2 307 vst1.16 {d0}, [r0, :64], r1 308 vst1.16 {d1}, [r0, :64], r1 309 bgt 4b 310 pop {r4-r11,pc} 31180: 312 add r8, r0, r1 313 lsl r1, r1, #1 314 add r9, r2, r3 315 lsl r3, r3, #1 3168: 317 vld1.16 {q0}, [r2], r3 318 vld1.16 {q1}, [r9], r3 319 subs r5, r5, #2 320 vst1.16 {q0}, [r0, :128], r1 321 vst1.16 {q1}, [r8, :128], r1 322 bgt 8b 323 pop {r4-r11,pc} 32416: 325 vld1.16 {q0, q1}, [r2], r3 326 subs r5, r5, #1 327 vst1.16 {q0, q1}, [r0, :128], r1 328 bgt 16b 329 pop {r4-r11,pc} 330320: 331 sub r1, r1, #32 332 sub r3, r3, #32 33332: 334 vld1.16 {q0, q1}, [r2]! 335 vst1.16 {q0, q1}, [r0, :128]! 336 vld1.16 {q2, q3}, [r2], r3 337 subs r5, r5, #1 338 vst1.16 {q2, q3}, [r0, :128], r1 339 bgt 32b 340 pop {r4-r11,pc} 341640: 342 sub r1, r1, #96 343 sub r3, r3, #96 34464: 345 vld1.16 {q8, q9}, [r2]! 346 vst1.16 {q8, q9}, [r0, :128]! 347 vld1.16 {q10, q11}, [r2]! 348 vst1.16 {q10, q11}, [r0, :128]! 349 vld1.16 {q12, q13}, [r2]! 350 vst1.16 {q12, q13}, [r0, :128]! 351 vld1.16 {q14, q15}, [r2], r3 352 subs r5, r5, #1 353 vst1.16 {q14, q15}, [r0, :128], r1 354 bgt 64b 355 pop {r4-r11,pc} 3561280: 357 sub r1, r1, #224 358 sub r3, r3, #224 359128: 360 vld1.16 {q8, q9}, [r2]! 361 vst1.16 {q8, q9}, [r0, :128]! 362 vld1.16 {q10, q11}, [r2]! 363 vst1.16 {q10, q11}, [r0, :128]! 364 vld1.16 {q12, q13}, [r2]! 365 vst1.16 {q12, q13}, [r0, :128]! 366 vld1.16 {q14, q15}, [r2]! 367 vst1.16 {q14, q15}, [r0, :128]! 368 vld1.16 {q8, q9}, [r2]! 369 vst1.16 {q8, q9}, [r0, :128]! 370 vld1.16 {q10, q11}, [r2]! 371 vst1.16 {q10, q11}, [r0, :128]! 372 vld1.16 {q12, q13}, [r2]! 373 vst1.16 {q12, q13}, [r0, :128]! 374 vld1.16 {q14, q15}, [r2], r3 375 subs r5, r5, #1 376 vst1.16 {q14, q15}, [r0, :128], r1 377 bgt 128b 378 pop {r4-r11,pc} 379endfunc 380 381// This has got the same signature as the prep_8tap functions, 382// and assumes that r9 is set to (clz(w)-24), r7 to intermediate_bits and 383// r8 to w*2. 384function prep_neon 385 adr r10, L(prep_tbl) 386 ldr r9, [r10, r9, lsl #2] 387 vdup.16 q15, r7 // intermediate_bits 388 vmov.i16 q14, #PREP_BIAS 389 add r10, r10, r9 390 bx r10 391 392 .align 2 393L(prep_tbl): 394 .word 1280f - L(prep_tbl) + CONFIG_THUMB 395 .word 640f - L(prep_tbl) + CONFIG_THUMB 396 .word 320f - L(prep_tbl) + CONFIG_THUMB 397 .word 16f - L(prep_tbl) + CONFIG_THUMB 398 .word 80f - L(prep_tbl) + CONFIG_THUMB 399 .word 40f - L(prep_tbl) + CONFIG_THUMB 400 40140: 402 add r9, r1, r2 403 lsl r2, r2, #1 4044: 405 vld1.16 {d0}, [r1], r2 406 vld1.16 {d1}, [r9], r2 407 subs r4, r4, #2 408 vshl.s16 q0, q0, q15 409 vsub.i16 q0, q0, q14 410 vst1.16 {q0}, [r0, :128]! 411 bgt 4b 412 pop {r4-r11,pc} 41380: 414 add r9, r1, r2 415 lsl r2, r2, #1 4168: 417 vld1.16 {q0}, [r1], r2 418 vld1.16 {q1}, [r9], r2 419 subs r4, r4, #2 420 vshl.s16 q0, q0, q15 421 vshl.s16 q1, q1, q15 422 vsub.i16 q0, q0, q14 423 vsub.i16 q1, q1, q14 424 vst1.16 {q0, q1}, [r0, :128]! 425 bgt 8b 426 pop {r4-r11,pc} 42716: 428 vld1.16 {q0, q1}, [r1], r2 429 vshl.s16 q0, q0, q15 430 vld1.16 {q2, q3}, [r1], r2 431 subs r4, r4, #2 432 vshl.s16 q1, q1, q15 433 vshl.s16 q2, q2, q15 434 vshl.s16 q3, q3, q15 435 vsub.i16 q0, q0, q14 436 vsub.i16 q1, q1, q14 437 vsub.i16 q2, q2, q14 438 vst1.16 {q0, q1}, [r0, :128]! 439 vsub.i16 q3, q3, q14 440 vst1.16 {q2, q3}, [r0, :128]! 441 bgt 16b 442 pop {r4-r11,pc} 443320: 444 sub r2, r2, #32 44532: 446 vld1.16 {q0, q1}, [r1]! 447 subs r4, r4, #1 448 vshl.s16 q0, q0, q15 449 vld1.16 {q2, q3}, [r1], r2 450 vshl.s16 q1, q1, q15 451 vshl.s16 q2, q2, q15 452 vshl.s16 q3, q3, q15 453 vsub.i16 q0, q0, q14 454 vsub.i16 q1, q1, q14 455 vsub.i16 q2, q2, q14 456 vst1.16 {q0, q1}, [r0, :128]! 457 vsub.i16 q3, q3, q14 458 vst1.16 {q2, q3}, [r0, :128]! 459 bgt 32b 460 pop {r4-r11,pc} 461640: 462 sub r2, r2, #96 46364: 464 vld1.16 {q0, q1}, [r1]! 465 subs r4, r4, #1 466 vshl.s16 q0, q0, q15 467 vld1.16 {q2, q3}, [r1]! 468 vshl.s16 q1, q1, q15 469 vld1.16 {q8, q9}, [r1]! 470 vshl.s16 q2, q2, q15 471 vld1.16 {q10, q11}, [r1], r2 472 vshl.s16 q3, q3, q15 473 vshl.s16 q8, q8, q15 474 vshl.s16 q9, q9, q15 475 vshl.s16 q10, q10, q15 476 vshl.s16 q11, q11, q15 477 vsub.i16 q0, q0, q14 478 vsub.i16 q1, q1, q14 479 vsub.i16 q2, q2, q14 480 vsub.i16 q3, q3, q14 481 vsub.i16 q8, q8, q14 482 vst1.16 {q0, q1}, [r0, :128]! 483 vsub.i16 q9, q9, q14 484 vst1.16 {q2, q3}, [r0, :128]! 485 vsub.i16 q10, q10, q14 486 vst1.16 {q8, q9}, [r0, :128]! 487 vsub.i16 q11, q11, q14 488 vst1.16 {q10, q11}, [r0, :128]! 489 bgt 64b 490 pop {r4-r11,pc} 4911280: 492 sub r2, r2, #224 493128: 494 vld1.16 {q0, q1}, [r1]! 495 subs r4, r4, #1 496 vshl.s16 q0, q0, q15 497 vld1.16 {q2, q3}, [r1]! 498 vshl.s16 q1, q1, q15 499 vld1.16 {q8, q9}, [r1]! 500 vshl.s16 q2, q2, q15 501 vld1.16 {q10, q11}, [r1]! 502 vshl.s16 q3, q3, q15 503 vshl.s16 q8, q8, q15 504 vshl.s16 q9, q9, q15 505 vshl.s16 q10, q10, q15 506 vshl.s16 q11, q11, q15 507 vsub.i16 q0, q0, q14 508 vsub.i16 q1, q1, q14 509 vsub.i16 q2, q2, q14 510 vsub.i16 q3, q3, q14 511 vsub.i16 q8, q8, q14 512 vst1.16 {q0, q1}, [r0, :128]! 513 vld1.16 {q0, q1}, [r1]! 514 vsub.i16 q9, q9, q14 515 vsub.i16 q10, q10, q14 516 vst1.16 {q2, q3}, [r0, :128]! 517 vld1.16 {q2, q3}, [r1]! 518 vsub.i16 q11, q11, q14 519 vshl.s16 q0, q0, q15 520 vst1.16 {q8, q9}, [r0, :128]! 521 vld1.16 {q8, q9}, [r1]! 522 vshl.s16 q1, q1, q15 523 vshl.s16 q2, q2, q15 524 vst1.16 {q10, q11}, [r0, :128]! 525 vld1.16 {q10, q11}, [r1], r2 526 vshl.s16 q3, q3, q15 527 vshl.s16 q8, q8, q15 528 vshl.s16 q9, q9, q15 529 vshl.s16 q10, q10, q15 530 vshl.s16 q11, q11, q15 531 vsub.i16 q0, q0, q14 532 vsub.i16 q1, q1, q14 533 vsub.i16 q2, q2, q14 534 vsub.i16 q3, q3, q14 535 vsub.i16 q8, q8, q14 536 vst1.16 {q0, q1}, [r0, :128]! 537 vsub.i16 q9, q9, q14 538 vst1.16 {q2, q3}, [r0, :128]! 539 vsub.i16 q10, q10, q14 540 vst1.16 {q8, q9}, [r0, :128]! 541 vsub.i16 q11, q11, q14 542 vst1.16 {q10, q11}, [r0, :128]! 543 bgt 128b 544 pop {r4-r11,pc} 545endfunc 546 547.macro load_slice s0, s1, strd, wd, d0, d1, d2, d3, d4, d5, d6 548 vld1.\wd {\d0[]}, [\s0], \strd 549 vld1.\wd {\d1[]}, [\s1], \strd 550.ifnb \d2 551 vld1.\wd {\d2[]}, [\s0], \strd 552 vld1.\wd {\d3[]}, [\s1], \strd 553.endif 554.ifnb \d4 555 vld1.\wd {\d4[]}, [\s0], \strd 556.endif 557.ifnb \d5 558 vld1.\wd {\d5[]}, [\s1], \strd 559.endif 560.ifnb \d6 561 vld1.\wd {\d6[]}, [\s0], \strd 562.endif 563.endm 564.macro load_reg s0, s1, strd, d0, d1, d2, d3, d4, d5, d6 565 vld1.16 {\d0}, [\s0], \strd 566 vld1.16 {\d1}, [\s1], \strd 567.ifnb \d2 568 vld1.16 {\d2}, [\s0], \strd 569 vld1.16 {\d3}, [\s1], \strd 570.endif 571.ifnb \d4 572 vld1.16 {\d4}, [\s0], \strd 573.endif 574.ifnb \d5 575 vld1.16 {\d5}, [\s1], \strd 576.endif 577.ifnb \d6 578 vld1.16 {\d6}, [\s0], \strd 579.endif 580.endm 581.macro load_regpair s0, s1, strd, d0, d1, d2, d3, d4, d5 582 vld1.16 {\d0, \d1}, [\s0], \strd 583.ifnb \d2 584 vld1.16 {\d2, \d3}, [\s1], \strd 585.endif 586.ifnb \d4 587 vld1.16 {\d4, \d5}, [\s0], \strd 588.endif 589.endm 590.macro load_32 s0, s1, strd, d0, d1, d2, d3, d4, d5, d6 591 load_slice \s0, \s1, \strd, 32, \d0, \d1, \d2, \d3, \d4, \d5, \d6 592.endm 593.macro load_16s16 s0, s1, strd, d0, d1, d2, d3, d4, d5 594 load_regpair \s0, \s1, \strd, \d0, \d1, \d2, \d3, \d4, \d5 595.endm 596.macro interleave_1_32 r0, r1, r2, r3, r4 597 vext.8 \r0, \r0, \r1, #4 598 vext.8 \r1, \r1, \r2, #4 599.ifnb \r3 600 vext.8 \r2, \r2, \r3, #4 601 vext.8 \r3, \r3, \r4, #4 602.endif 603.endm 604.macro vmin_u16 c, r0, r1, r2, r3 605 vmin.u16 \r0, \r0, \c 606.ifnb \r1 607 vmin.u16 \r1, \r1, \c 608.endif 609.ifnb \r2 610 vmin.u16 \r2, \r2, \c 611 vmin.u16 \r3, \r3, \c 612.endif 613.endm 614.macro vsub_i16 c, r0, r1, r2, r3 615 vsub.i16 \r0, \r0, \c 616.ifnb \r1 617 vsub.i16 \r1, \r1, \c 618.endif 619.ifnb \r2 620 vsub.i16 \r2, \r2, \c 621 vsub.i16 \r3, \r3, \c 622.endif 623.endm 624.macro vmull_vmlal_4 d, s0, s1, s2, s3 625 vmull.s16 \d, \s0, d0[0] 626 vmlal.s16 \d, \s1, d0[1] 627 vmlal.s16 \d, \s2, d0[2] 628 vmlal.s16 \d, \s3, d0[3] 629.endm 630.macro vmull_vmlal_8 d, s0, s1, s2, s3, s4, s5, s6, s7 631 vmull.s16 \d, \s0, d0[0] 632 vmlal.s16 \d, \s1, d0[1] 633 vmlal.s16 \d, \s2, d0[2] 634 vmlal.s16 \d, \s3, d0[3] 635 vmlal.s16 \d, \s4, d1[0] 636 vmlal.s16 \d, \s5, d1[1] 637 vmlal.s16 \d, \s6, d1[2] 638 vmlal.s16 \d, \s7, d1[3] 639.endm 640.macro vqrshrun_s32 shift, q0, d0, q1, d1, q2, d2, q3, d3 641 vqrshrun.s32 \d0, \q0, #\shift 642.ifnb \q1 643 vqrshrun.s32 \d1, \q1, #\shift 644.endif 645.ifnb \q2 646 vqrshrun.s32 \d2, \q2, #\shift 647 vqrshrun.s32 \d3, \q3, #\shift 648.endif 649.endm 650.macro vmovn_i32 q0, d0, q1, d1, q2, d2, q3, d3 651 vmovn.i32 \d0, \q0 652.ifnb \q1 653 vmovn.i32 \d1, \q1 654.endif 655.ifnb \q2 656 vmovn.i32 \d2, \q2 657 vmovn.i32 \d3, \q3 658.endif 659.endm 660.macro vrshl_s32 shift, r0, r1, r2, r3 661 vrshl.s32 \r0, \r0, \shift 662 vrshl.s32 \r1, \r1, \shift 663.ifnb \r2 664 vrshl.s32 \r2, \r2, \shift 665 vrshl.s32 \r3, \r3, \shift 666.endif 667.endm 668.macro vst1_32 strd, r0, r1 669 vst1.32 {\r0[0]}, [r0, :32], \strd 670 vst1.32 {\r0[1]}, [r9, :32], \strd 671.ifnb \r1 672 vst1.32 {\r1[0]}, [r0, :32], \strd 673 vst1.32 {\r1[1]}, [r9, :32], \strd 674.endif 675.endm 676.macro vst1_reg strd, align, r0, r1, r2, r3, r4, r5, r6, r7 677 vst1.16 {\r0}, [r0, \align], \strd 678 vst1.16 {\r1}, [r9, \align], \strd 679.ifnb \r2 680 vst1.16 {\r2}, [r0, \align], \strd 681 vst1.16 {\r3}, [r9, \align], \strd 682.endif 683.ifnb \r4 684 vst1.16 {\r4}, [r0, \align], \strd 685 vst1.16 {\r5}, [r9, \align], \strd 686 vst1.16 {\r6}, [r0, \align], \strd 687 vst1.16 {\r7}, [r9, \align], \strd 688.endif 689.endm 690.macro finalize type, q0, q1, d0, d1, q2, q3, d2, d3 691.ifc \type, put 692 vqrshrun_s32 6, \q0, \d0, \q1, \d1, \q2, \d2, \q3, \d3 693 vmin_u16 q15, \q0, \q1 694.else 695 vrshl_s32 q14, \q0, \q1, \q2, \q3 // -(6-intermediate_bits) 696 vmovn_i32 \q0, \d0, \q1, \d1, \q2, \d2, \q3, \d3 697 vsub_i16 q15, \q0, \q1 // PREP_BIAS 698.endif 699.endm 700.macro shift_store_4 type, strd, q0, q1, d0, d1, q2, q3, d2, d3 701 finalize \type, \q0, \q1, \d0, \d1, \q2, \q3, \d2, \d3 702 vst1_reg \strd, :64, \d0, \d1, \d2, \d3 703.endm 704.macro shift_store_8 type, strd, q0, q1, d0, d1, q2, q3, d2, d3 705 finalize \type, \q0, \q1, \d0, \d1, \q2, \q3, \d2, \d3 706 vst1_reg \strd, :128, \q0, \q1 707.endm 708.macro shift_store_16 type, strd, q0, q1, d0, d1, q2, q3, d2, d3 709 finalize \type, \q0, \q1, \d0, \d1, \q2, \q3, \d2, \d3 710 vst1.16 {\q0, \q1}, [r0, :128], \strd 711.endm 712 713.macro make_8tap_fn op, type, type_h, type_v 714function \op\()_8tap_\type\()_16bpc_neon, export=1 715 push {r4-r11,lr} 716 movw r9, \type_h 717 movw r10, \type_v 718 b \op\()_8tap_neon 719endfunc 720.endm 721 722// No spaces in these expressions, due to gas-preprocessor. 723#define REGULAR ((0*15<<7)|3*15) 724#define SMOOTH ((1*15<<7)|4*15) 725#define SHARP ((2*15<<7)|3*15) 726 727.macro filter_fn type, dst, d_strd, src, s_strd, w, h, mx, my, bdmax, ds2, sr2 728make_8tap_fn \type, regular, REGULAR, REGULAR 729make_8tap_fn \type, regular_smooth, REGULAR, SMOOTH 730make_8tap_fn \type, regular_sharp, REGULAR, SHARP 731make_8tap_fn \type, smooth, SMOOTH, SMOOTH 732make_8tap_fn \type, smooth_regular, SMOOTH, REGULAR 733make_8tap_fn \type, smooth_sharp, SMOOTH, SHARP 734make_8tap_fn \type, sharp, SHARP, SHARP 735make_8tap_fn \type, sharp_regular, SHARP, REGULAR 736make_8tap_fn \type, sharp_smooth, SHARP, SMOOTH 737 738function \type\()_8tap_neon 739 ldrd r4, r5, [sp, #36] 740 ldrd r6, r7, [sp, #44] 741.ifc \bdmax, r8 742 ldr r8, [sp, #52] 743.endif 744 movw r11, #0x4081 // (1 << 14) | (1 << 7) | (1 << 0) 745 mul \mx, \mx, r11 746 mul \my, \my, r11 747 add \mx, \mx, r9 // mx, 8tap_h, 4tap_h 748 add \my, \my, r10 // my, 8tap_v, 4tap_v 749 750.ifc \type, prep 751 lsl \d_strd, \w, #1 752.endif 753 754 vdup.16 q15, \bdmax // bitdepth_max 755 clz \bdmax, \bdmax 756 clz r9, \w 757 sub \bdmax, \bdmax, #18 // intermediate_bits = clz(bitdepth_max) - 18 758 tst \mx, #(0x7f << 14) 759 sub r9, r9, #24 760 add lr, \bdmax, #6 // 6 + intermediate_bits 761 rsb r12, \bdmax, #6 // 6 - intermediate_bits 762 movrel r11, X(mc_subpel_filters), -8 763 bne L(\type\()_8tap_h) 764 tst \my, #(0x7f << 14) 765 bne L(\type\()_8tap_v) 766 b \type\()_neon 767 768L(\type\()_8tap_h): 769 cmp \w, #4 770 ubfx r10, \mx, #7, #7 771 and \mx, \mx, #0x7f 772 it gt 773 movgt \mx, r10 774 tst \my, #(0x7f << 14) 775 add \mx, r11, \mx, lsl #3 776 bne L(\type\()_8tap_hv) 777 778 adr r10, L(\type\()_8tap_h_tbl) 779 vdup.32 q14, r12 // 6 - intermediate_bits 780 ldr r9, [r10, r9, lsl #2] 781 vneg.s32 q14, q14 // -(6-intermediate_bits) 782.ifc \type, put 783 vdup.16 q13, \bdmax // intermediate_bits 784.else 785 vmov.i16 q13, #PREP_BIAS 786.endif 787 add r10, r10, r9 788.ifc \type, put 789 vneg.s16 q13, q13 // -intermediate_bits 790.endif 791 bx r10 792 793 .align 2 794L(\type\()_8tap_h_tbl): 795 .word 1280f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 796 .word 640f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 797 .word 320f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 798 .word 160f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 799 .word 80f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 800 .word 40f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 801 .word 20f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 802 80320: // 2xN h 804.ifc \type, put 805 add \mx, \mx, #2 806 vld1.32 {d0[]}, [\mx] 807 sub \src, \src, #2 808 add \ds2, \dst, \d_strd 809 add \sr2, \src, \s_strd 810 lsl \d_strd, \d_strd, #1 811 lsl \s_strd, \s_strd, #1 812 vmovl.s8 q0, d0 8132: 814 vld1.16 {q2}, [\src], \s_strd 815 vld1.16 {q3}, [\sr2], \s_strd 816 vext.8 d5, d4, d5, #2 817 vext.8 d7, d6, d7, #2 818 subs \h, \h, #2 819 vtrn.32 d4, d6 820 vtrn.32 d5, d7 821 vmull.s16 q1, d4, d0[0] 822 vmlal.s16 q1, d5, d0[1] 823 vmlal.s16 q1, d6, d0[2] 824 vmlal.s16 q1, d7, d0[3] 825 vrshl.s32 q1, q1, q14 // -(6-intermediate_bits) 826 vqmovun.s32 d2, q1 827 vrshl.s16 d2, d2, d26 // -intermediate_bits 828 vmin.u16 d2, d2, d30 829 vst1.32 {d2[0]}, [\dst, :32], \d_strd 830 vst1.32 {d2[1]}, [\ds2, :32], \d_strd 831 bgt 2b 832 pop {r4-r11,pc} 833.endif 834 83540: // 4xN h 836 add \mx, \mx, #2 837 vld1.32 {d0[]}, [\mx] 838 sub \src, \src, #2 839 add \ds2, \dst, \d_strd 840 add \sr2, \src, \s_strd 841 lsl \d_strd, \d_strd, #1 842 lsl \s_strd, \s_strd, #1 843 vmovl.s8 q0, d0 8444: 845 vld1.16 {q8}, [\src], \s_strd 846 vld1.16 {q11}, [\sr2], \s_strd 847 vext.8 d18, d16, d17, #2 848 vext.8 d19, d16, d17, #4 849 vext.8 d20, d16, d17, #6 850 vext.8 d24, d22, d23, #2 851 vext.8 d25, d22, d23, #4 852 vext.8 d21, d22, d23, #6 853 subs \h, \h, #2 854 vmull.s16 q2, d16, d0[0] 855 vmlal.s16 q2, d18, d0[1] 856 vmlal.s16 q2, d19, d0[2] 857 vmlal.s16 q2, d20, d0[3] 858 vmull.s16 q3, d22, d0[0] 859 vmlal.s16 q3, d24, d0[1] 860 vmlal.s16 q3, d25, d0[2] 861 vmlal.s16 q3, d21, d0[3] 862 vrshl.s32 q2, q2, q14 // -(6-intermediate_bits) 863 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 864.ifc \type, put 865 vqmovun.s32 d4, q2 866 vqmovun.s32 d5, q3 867 vrshl.s16 q2, q2, q13 // -intermediate_bits 868 vmin.u16 q2, q2, q15 869.else 870 vmovn.s32 d4, q2 871 vmovn.s32 d5, q3 872 vsub.i16 q2, q2, q13 // PREP_BIAS 873.endif 874 vst1.16 {d4}, [\dst, :64], \d_strd 875 vst1.16 {d5}, [\ds2, :64], \d_strd 876 bgt 4b 877 pop {r4-r11,pc} 878 87980: 880160: 881320: 882640: 8831280: // 8xN, 16xN, 32xN, ... h 884 vpush {q4-q5} 885 vld1.8 {d0}, [\mx, :64] 886 sub \src, \src, #6 887 add \ds2, \dst, \d_strd 888 add \sr2, \src, \s_strd 889 lsl \s_strd, \s_strd, #1 890 vmovl.s8 q0, d0 891 892 sub \s_strd, \s_strd, \w, lsl #1 893 sub \s_strd, \s_strd, #16 894.ifc \type, put 895 lsl \d_strd, \d_strd, #1 896 sub \d_strd, \d_strd, \w, lsl #1 897.endif 89881: 899 vld1.16 {q8, q9}, [\src]! 900 vld1.16 {q10, q11}, [\sr2]! 901 mov \mx, \w 902 9038: 904 vmull.s16 q1, d16, d0[0] 905 vmull.s16 q2, d17, d0[0] 906 vmull.s16 q3, d20, d0[0] 907 vmull.s16 q4, d21, d0[0] 908.irpc i, 1234567 909 vext.8 q12, q8, q9, #(2*\i) 910 vext.8 q5, q10, q11, #(2*\i) 911.if \i < 4 912 vmlal.s16 q1, d24, d0[\i] 913 vmlal.s16 q2, d25, d0[\i] 914 vmlal.s16 q3, d10, d0[\i] 915 vmlal.s16 q4, d11, d0[\i] 916.else 917 vmlal.s16 q1, d24, d1[\i-4] 918 vmlal.s16 q2, d25, d1[\i-4] 919 vmlal.s16 q3, d10, d1[\i-4] 920 vmlal.s16 q4, d11, d1[\i-4] 921.endif 922.endr 923 subs \mx, \mx, #8 924 vrshl.s32 q1, q1, q14 // -(6-intermediate_bits) 925 vrshl.s32 q2, q2, q14 // -(6-intermediate_bits) 926 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 927 vrshl.s32 q4, q4, q14 // -(6-intermediate_bits) 928.ifc \type, put 929 vqmovun.s32 d2, q1 930 vqmovun.s32 d3, q2 931 vqmovun.s32 d4, q3 932 vqmovun.s32 d5, q4 933 vrshl.s16 q1, q1, q13 // -intermediate_bits 934 vrshl.s16 q2, q2, q13 // -intermediate_bits 935 vmin.u16 q1, q1, q15 936 vmin.u16 q2, q2, q15 937.else 938 vmovn.s32 d2, q1 939 vmovn.s32 d3, q2 940 vmovn.s32 d4, q3 941 vmovn.s32 d5, q4 942 vsub.i16 q1, q1, q13 // PREP_BIAS 943 vsub.i16 q2, q2, q13 // PREP_BIAS 944.endif 945 vst1.16 {q1}, [\dst, :128]! 946 vst1.16 {q2}, [\ds2, :128]! 947 ble 9f 948 949 vmov q8, q9 950 vmov q10, q11 951 vld1.16 {q9}, [\src]! 952 vld1.16 {q11}, [\sr2]! 953 b 8b 954 9559: 956 add \dst, \dst, \d_strd 957 add \ds2, \ds2, \d_strd 958 add \src, \src, \s_strd 959 add \sr2, \sr2, \s_strd 960 961 subs \h, \h, #2 962 bgt 81b 963 vpop {q4-q5} 964 pop {r4-r11,pc} 965 966 967L(\type\()_8tap_v): 968 cmp \h, #4 969 ubfx r10, \my, #7, #7 970 and \my, \my, #0x7f 971 it gt 972 movgt \my, r10 973 add \my, r11, \my, lsl #3 974 975.ifc \type, prep 976 vdup.32 q14, r12 // 6 - intermediate_bits 977 vmov.i16 q15, #PREP_BIAS 978.endif 979 adr r10, L(\type\()_8tap_v_tbl) 980 ldr r9, [r10, r9, lsl #2] 981.ifc \type, prep 982 vneg.s32 q14, q14 // -(6-intermediate_bits) 983.endif 984 add r10, r10, r9 985 bx r10 986 987 .align 2 988L(\type\()_8tap_v_tbl): 989 .word 1280f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 990 .word 640f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 991 .word 320f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 992 .word 160f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 993 .word 80f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 994 .word 40f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 995 .word 20f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 996 99720: // 2xN v 998.ifc \type, put 999 bgt 28f 1000 1001 cmp \h, #2 1002 add \my, \my, #2 1003 vld1.32 {d0[]}, [\my] 1004 sub \src, \src, \s_strd 1005 add \ds2, \dst, \d_strd 1006 add \sr2, \src, \s_strd 1007 lsl \s_strd, \s_strd, #1 1008 lsl \d_strd, \d_strd, #1 1009 vmovl.s8 q0, d0 1010 1011 // 2x2 v 1012 load_32 \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1013 interleave_1_32 d1, d2, d3, d4, d5 1014 bgt 24f 1015 vmull_vmlal_4 q8, d1, d2, d3, d4 1016 vqrshrun_s32 6, q8, d16 1017 vmin_u16 d30, d16 1018 vst1_32 \d_strd, d16 1019 pop {r4-r11,pc} 1020 102124: // 2x4 v 1022 load_32 \sr2, \src, \s_strd, d6, d7 1023 interleave_1_32 d5, d6, d7 1024 vmull_vmlal_4 q8, d1, d2, d3, d4 1025 vmull_vmlal_4 q9, d3, d4, d5, d6 1026 vqrshrun_s32 6, q8, d16, q9, d17 1027 vmin_u16 q15, q8 1028 vst1_32 \d_strd, d16, d17 1029 pop {r4-r11,pc} 1030 103128: // 2x8, 2x16 v 1032 vld1.8 {d0}, [\my, :64] 1033 sub \sr2, \src, \s_strd, lsl #1 1034 add \ds2, \dst, \d_strd 1035 sub \src, \sr2, \s_strd 1036 lsl \d_strd, \d_strd, #1 1037 lsl \s_strd, \s_strd, #1 1038 vmovl.s8 q0, d0 1039 1040 load_32 \src, \sr2, \s_strd, d2, d3, d4, d5, d6, d7, d16 1041 interleave_1_32 d2, d3, d4, d5, d6 1042 interleave_1_32 d6, d7, d16 1043216: 1044 subs \h, \h, #8 1045 load_32 \sr2, \src, \s_strd, d17, d18, d19, d20 1046 load_32 \sr2, \src, \s_strd, d21, d22, d23, d24 1047 interleave_1_32 d16, d17, d18, d19, d20 1048 interleave_1_32 d20, d21, d22, d23, d24 1049 vmull_vmlal_8 q13, d2, d3, d4, d5, d6, d7, d16, d17 1050 vmull_vmlal_8 q1, d4, d5, d6, d7, d16, d17, d18, d19 1051 vmull_vmlal_8 q2, d6, d7, d16, d17, d18, d19, d20, d21 1052 vmull_vmlal_8 q3, d16, d17, d18, d19, d20, d21, d22, d23 1053 vqrshrun_s32 6, q13, d26, q1, d27, q2, d2, q3, d3 1054 vmin_u16 q15, q13, q1 1055 vst1_32 \d_strd, d26, d27 1056 vst1_32 \d_strd, d2, d3 1057 ble 0f 1058 vmov q1, q9 1059 vmov q2, q10 1060 vmov q3, q11 1061 vmov d16, d24 1062 b 216b 10630: 1064 pop {r4-r11,pc} 1065.endif 1066 106740: 1068 bgt 480f 1069 1070 // 4x2, 4x4 v 1071 cmp \h, #2 1072 add \my, \my, #2 1073 vld1.32 {d0[]}, [\my] 1074 sub \src, \src, \s_strd 1075 add \ds2, \dst, \d_strd 1076 add \sr2, \src, \s_strd 1077 lsl \s_strd, \s_strd, #1 1078 lsl \d_strd, \d_strd, #1 1079 vmovl.s8 q0, d0 1080 1081 load_reg \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1082 vmull_vmlal_4 q8, d1, d2, d3, d4 1083 vmull_vmlal_4 q9, d2, d3, d4, d5 1084 shift_store_4 \type, \d_strd, q8, q9, d16, d17 1085 ble 0f 1086 load_reg \sr2, \src, \s_strd, d6, d7 1087 vmull_vmlal_4 q8, d3, d4, d5, d6 1088 vmull_vmlal_4 q9, d4, d5, d6, d7 1089 shift_store_4 \type, \d_strd, q8, q9, d16, d17 10900: 1091 pop {r4-r11,pc} 1092 1093480: // 4x8, 4x16 v 1094 vld1.8 {d0}, [\my, :64] 1095 sub \sr2, \src, \s_strd, lsl #1 1096 add \ds2, \dst, \d_strd 1097 sub \src, \sr2, \s_strd 1098 lsl \s_strd, \s_strd, #1 1099 lsl \d_strd, \d_strd, #1 1100 vmovl.s8 q0, d0 1101 1102 load_reg \src, \sr2, \s_strd, d16, d17, d18, d19, d20, d21, d22 1103 110448: 1105 subs \h, \h, #4 1106 load_reg \sr2, \src, \s_strd, d23, d24, d25, d26 1107 vmull_vmlal_8 q1, d16, d17, d18, d19, d20, d21, d22, d23 1108 vmull_vmlal_8 q2, d17, d18, d19, d20, d21, d22, d23, d24 1109 vmull_vmlal_8 q3, d18, d19, d20, d21, d22, d23, d24, d25 1110 vmull_vmlal_8 q8, d19, d20, d21, d22, d23, d24, d25, d26 1111 shift_store_4 \type, \d_strd, q1, q2, d2, d3, q3, q8, d4, d5 1112 ble 0f 1113 vmov q8, q10 1114 vmov q9, q11 1115 vmov q10, q12 1116 vmov d22, d26 1117 b 48b 11180: 1119 pop {r4-r11,pc} 1120 112180: 1122 bgt 880f 1123 1124 // 8x2, 8x4 v 1125 cmp \h, #2 1126 add \my, \my, #2 1127 vld1.32 {d0[]}, [\my] 1128 sub \src, \src, \s_strd 1129 add \ds2, \dst, \d_strd 1130 add \sr2, \src, \s_strd 1131 lsl \s_strd, \s_strd, #1 1132 lsl \d_strd, \d_strd, #1 1133 vmovl.s8 q0, d0 1134 1135 load_reg \src, \sr2, \s_strd, q1, q2, q3, q8, q9 1136 vmull_vmlal_4 q10, d2, d4, d6, d16 1137 vmull_vmlal_4 q11, d3, d5, d7, d17 1138 vmull_vmlal_4 q12, d4, d6, d16, d18 1139 vmull_vmlal_4 q13, d5, d7, d17, d19 1140 shift_store_8 \type, \d_strd, q10, q11, d20, d21, q12, q13, d22, d23 1141 ble 0f 1142 load_reg \sr2, \src, \s_strd, q10, q11 1143 vmull_vmlal_4 q1, d6, d16, d18, d20 1144 vmull_vmlal_4 q2, d7, d17, d19, d21 1145 vmull_vmlal_4 q12, d16, d18, d20, d22 1146 vmull_vmlal_4 q13, d17, d19, d21, d23 1147 shift_store_8 \type, \d_strd, q1, q2, d2, d3, q12, q13, d4, d5 11480: 1149 pop {r4-r11,pc} 1150 1151880: // 8x6, 8x8, 8x16, 8x32 v 11521680: // 16x8, 16x16, ... 1153320: // 32x8, 32x16, ... 1154640: 11551280: 1156 vpush {q4-q7} 1157 vld1.8 {d0}, [\my, :64] 1158 sub \src, \src, \s_strd 1159 sub \src, \src, \s_strd, lsl #1 1160 vmovl.s8 q0, d0 1161 mov \my, \h 1162168: 1163 add \ds2, \dst, \d_strd 1164 add \sr2, \src, \s_strd 1165 lsl \s_strd, \s_strd, #1 1166 lsl \d_strd, \d_strd, #1 1167 1168 load_reg \src, \sr2, \s_strd, q5, q6, q7, q8, q9, q10, q11 1169 117088: 1171 subs \h, \h, #2 1172 load_reg \sr2, \src, \s_strd, q12, q13 1173 vmull_vmlal_8 q1, d10, d12, d14, d16, d18, d20, d22, d24 1174 vmull_vmlal_8 q2, d11, d13, d15, d17, d19, d21, d23, d25 1175 vmull_vmlal_8 q3, d12, d14, d16, d18, d20, d22, d24, d26 1176 vmull_vmlal_8 q4, d13, d15, d17, d19, d21, d23, d25, d27 1177 shift_store_8 \type, \d_strd, q1, q2, d2, d3, q3, q4, d4, d5 1178 ble 9f 1179 subs \h, \h, #2 1180 load_reg \sr2, \src, \s_strd, q1, q2 1181 vmull_vmlal_8 q3, d14, d16, d18, d20, d22, d24, d26, d2 1182 vmull_vmlal_8 q4, d15, d17, d19, d21, d23, d25, d27, d3 1183 vmull_vmlal_8 q5, d16, d18, d20, d22, d24, d26, d2, d4 1184 vmull_vmlal_8 q6, d17, d19, d21, d23, d25, d27, d3, d5 1185 shift_store_8 \type, \d_strd, q3, q4, d6, d7, q5, q6, d8, d9 1186 ble 9f 1187 vmov q5, q9 1188 vmov q6, q10 1189 vmov q7, q11 1190 vmov q8, q12 1191 vmov q9, q13 1192 vmov q10, q1 1193 vmov q11, q2 1194 b 88b 11959: 1196 subs \w, \w, #8 1197 ble 0f 1198 asr \s_strd, \s_strd, #1 1199 asr \d_strd, \d_strd, #1 1200 mls \src, \s_strd, \my, \src 1201 mls \dst, \d_strd, \my, \dst 1202 sub \src, \src, \s_strd, lsl #3 1203 mov \h, \my 1204 add \src, \src, #16 1205 add \dst, \dst, #16 1206 b 168b 12070: 1208 vpop {q4-q7} 1209 pop {r4-r11,pc} 1210 1211160: 1212 bgt 1680b 1213 1214 // 16x2, 16x4 v 1215 vpush {q6-q7} 1216 add \my, \my, #2 1217 vld1.32 {d0[]}, [\my] 1218 sub \src, \src, \s_strd 1219 vmovl.s8 q0, d0 1220 1221 load_16s16 \src, \src, \s_strd, q6, q7, q8, q9, q10, q11 122216: 1223 load_16s16 \src, \src, \s_strd, q12, q13 1224 subs \h, \h, #1 1225 vmull_vmlal_4 q1, d12, d16, d20, d24 1226 vmull_vmlal_4 q2, d13, d17, d21, d25 1227 vmull_vmlal_4 q3, d14, d18, d22, d26 1228 vmull_vmlal_4 q6, d15, d19, d23, d27 1229 shift_store_16 \type, \d_strd, q1, q2, d2, d3, q3, q6, d4, d5 1230 ble 0f 1231 vmov q6, q8 1232 vmov q7, q9 1233 vmov q8, q10 1234 vmov q9, q11 1235 vmov q10, q12 1236 vmov q11, q13 1237 b 16b 12380: 1239 vpop {q6-q7} 1240 pop {r4-r11,pc} 1241 1242 1243L(\type\()_8tap_hv): 1244 cmp \h, #4 1245 ubfx r10, \my, #7, #7 1246 and \my, \my, #0x7f 1247 it gt 1248 movgt \my, r10 12494: 1250 add \my, r11, \my, lsl #3 1251 1252 adr r10, L(\type\()_8tap_hv_tbl) 1253 neg r12, r12 // -(6-intermediate_bits) 1254 ldr r9, [r10, r9, lsl #2] 1255 vdup.32 q14, r12 // -(6-intermediate_bits) 1256.ifc \type, put 1257 neg r8, lr // -(6+intermeidate_bits) 1258.else 1259 vmov.i16 q13, #PREP_BIAS 1260.endif 1261 add r10, r10, r9 1262.ifc \type, put 1263 vdup.32 q13, r8 // -(6+intermediate_bits) 1264.endif 1265 bx r10 1266 1267 .align 2 1268L(\type\()_8tap_hv_tbl): 1269 .word 1280f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1270 .word 640f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1271 .word 320f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1272 .word 160f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1273 .word 80f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1274 .word 40f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1275 .word 20f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1276 127720: 1278.ifc \type, put 1279 add \mx, \mx, #2 1280 vld1.32 {d0[]}, [\mx] 1281 bgt 280f 1282 add \my, \my, #2 1283 vld1.32 {d2[]}, [\my] 1284 1285 // 2x2, 2x4 hv 1286 sub \sr2, \src, #2 1287 sub \src, \sr2, \s_strd 1288 add \ds2, \dst, \d_strd 1289 lsl \s_strd, \s_strd, #1 1290 lsl \d_strd, \d_strd, #1 1291 vmovl.s8 q0, d0 1292 vmovl.s8 q1, d2 1293 1294 vld1.16 {q11}, [\src], \s_strd 1295 vext.8 d24, d22, d23, #2 1296 vmull.s16 q11, d22, d0 1297 vmull.s16 q12, d24, d0 1298 vpadd.s32 d22, d22, d23 1299 vpadd.s32 d23, d24, d25 1300 vpadd.s32 d22, d22, d23 1301 vrshl.s32 d16, d22, d28 // -(6-intermediate_bits) 1302 vmovn.i32 d16, q8 1303 bl L(\type\()_8tap_filter_2) 1304 1305 vext.8 d16, d16, d16, #4 1306 vext.8 d16, d16, d24, #4 1307 vmov d17, d24 1308 13092: 1310 bl L(\type\()_8tap_filter_2) 1311 1312 vext.8 d18, d17, d24, #4 1313 vmull.s16 q2, d16, d2[0] 1314 vmlal.s16 q2, d17, d2[1] 1315 vmlal.s16 q2, d18, d2[2] 1316 vmlal.s16 q2, d24, d2[3] 1317 1318 vrshl.s32 q2, q2, q13 // -(6+intermediate_bits) 1319 vqmovun.s32 d4, q2 1320 vmin.u16 d4, d4, d30 1321 subs \h, \h, #2 1322 vst1.32 {d4[0]}, [\dst, :32], \d_strd 1323 vst1.32 {d4[1]}, [\ds2, :32], \d_strd 1324 ble 0f 1325 vmov d16, d18 1326 vmov d17, d24 1327 b 2b 1328 1329280: // 2x8, 2x16, 2x32 hv 1330 vld1.8 {d2}, [\my, :64] 1331 sub \src, \src, #2 1332 sub \sr2, \src, \s_strd, lsl #1 1333 sub \src, \sr2, \s_strd 1334 add \ds2, \dst, \d_strd 1335 lsl \s_strd, \s_strd, #1 1336 lsl \d_strd, \d_strd, #1 1337 vmovl.s8 q0, d0 1338 vmovl.s8 q1, d2 1339 1340 vld1.16 {q11}, [\src], \s_strd 1341 vext.8 d24, d22, d23, #2 1342 vmull.s16 q11, d22, d0 1343 vmull.s16 q12, d24, d0 1344 vpadd.s32 d22, d22, d23 1345 vpadd.s32 d23, d24, d25 1346 vpadd.s32 d22, d22, d23 1347 vrshl.s32 d16, d22, d28 // -(6-intermediate_bits) 1348 vmovn.i32 d16, q8 1349 1350 bl L(\type\()_8tap_filter_2) 1351 1352 vext.8 d16, d16, d16, #4 1353 vext.8 d16, d16, d24, #4 1354 vmov d17, d24 1355 bl L(\type\()_8tap_filter_2) 1356 vext.8 d18, d17, d24, #4 1357 vmov d19, d24 1358 bl L(\type\()_8tap_filter_2) 1359 vext.8 d20, d19, d24, #4 1360 vmov d21, d24 1361 136228: 1363 bl L(\type\()_8tap_filter_2) 1364 vext.8 d22, d21, d24, #4 1365 vmull.s16 q3, d16, d2[0] 1366 vmlal.s16 q3, d17, d2[1] 1367 vmlal.s16 q3, d18, d2[2] 1368 vmlal.s16 q3, d19, d2[3] 1369 vmlal.s16 q3, d20, d3[0] 1370 vmlal.s16 q3, d21, d3[1] 1371 vmlal.s16 q3, d22, d3[2] 1372 vmlal.s16 q3, d24, d3[3] 1373 1374 vrshl.s32 q3, q3, q13 // -(6+intermediate_bits) 1375 vqmovun.s32 d6, q3 1376 vmin.u16 d6, d6, d30 1377 subs \h, \h, #2 1378 vst1.32 {d6[0]}, [\dst, :32], \d_strd 1379 vst1.32 {d6[1]}, [\ds2, :32], \d_strd 1380 ble 0f 1381 vmov q8, q9 1382 vmov q9, q10 1383 vmov d20, d22 1384 vmov d21, d24 1385 b 28b 13860: 1387 pop {r4-r11,pc} 1388 1389L(\type\()_8tap_filter_2): 1390 vld1.16 {q11}, [\sr2], \s_strd 1391 vld1.16 {q12}, [\src], \s_strd 1392 vext.8 d23, d22, d23, #2 1393 vext.8 d25, d24, d25, #2 1394 vtrn.32 q11, q12 1395 vmull.s16 q3, d22, d0[0] 1396 vmlal.s16 q3, d23, d0[1] 1397 vmlal.s16 q3, d24, d0[2] 1398 vmlal.s16 q3, d25, d0[3] 1399 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 1400 vmovn.i32 d24, q3 1401 bx lr 1402.endif 1403 140440: 1405 add \mx, \mx, #2 1406 vld1.32 {d0[]}, [\mx] 1407 bgt 480f 1408 add \my, \my, #2 1409 vld1.32 {d2[]}, [\my] 1410 sub \sr2, \src, #2 1411 sub \src, \sr2, \s_strd 1412 add \ds2, \dst, \d_strd 1413 lsl \s_strd, \s_strd, #1 1414 lsl \d_strd, \d_strd, #1 1415 vmovl.s8 q0, d0 1416 vmovl.s8 q1, d2 1417 1418 // 4x2, 4x4 hv 1419 vld1.16 {q11}, [\src], \s_strd 1420 vext.8 d24, d22, d23, #2 1421 vext.8 d25, d22, d23, #4 1422 vext.8 d23, d22, d23, #6 1423 vmull.s16 q10, d22, d0[0] 1424 vmlal.s16 q10, d24, d0[1] 1425 vmlal.s16 q10, d25, d0[2] 1426 vmlal.s16 q10, d23, d0[3] 1427 vrshl.s32 q10, q10, q14 // -(6-intermediate_bits) 1428 vmovn.i32 d17, q10 1429 1430 bl L(\type\()_8tap_filter_4) 1431 vmov q9, q12 1432 14334: 1434 bl L(\type\()_8tap_filter_4) 1435 vmull.s16 q2, d17, d2[0] 1436 vmlal.s16 q2, d18, d2[1] 1437 vmlal.s16 q2, d19, d2[2] 1438 vmlal.s16 q2, d24, d2[3] 1439 vmull.s16 q3, d18, d2[0] 1440 vmlal.s16 q3, d19, d2[1] 1441 vmlal.s16 q3, d24, d2[2] 1442 vmlal.s16 q3, d25, d2[3] 1443.ifc \type, put 1444 vrshl.s32 q2, q2, q13 // -(6+intermediate_bits) 1445 vrshl.s32 q3, q3, q13 // -(6+intermediate_bits) 1446 vqmovun.s32 d4, q2 1447 vqmovun.s32 d5, q3 1448 vmin.u16 q2, q2, q15 1449.else 1450 vrshrn.i32 d4, q2, #6 1451 vrshrn.i32 d5, q3, #6 1452 vsub.i16 q2, q2, q13 // PREP_BIAS 1453.endif 1454 subs \h, \h, #2 1455 1456 vst1.16 {d4}, [\dst, :64], \d_strd 1457 vst1.16 {d5}, [\ds2, :64], \d_strd 1458 ble 0f 1459 vmov d17, d19 1460 vmov q9, q12 1461 b 4b 14620: 1463 pop {r4-r11,pc} 1464 1465480: // 4x8, 4x16, 4x32 hv 1466 vpush {d13-d15} 1467 vld1.8 {d2}, [\my, :64] 1468 sub \src, \src, #2 1469 sub \sr2, \src, \s_strd, lsl #1 1470 sub \src, \sr2, \s_strd 1471 add \ds2, \dst, \d_strd 1472 lsl \s_strd, \s_strd, #1 1473 lsl \d_strd, \d_strd, #1 1474 vmovl.s8 q0, d0 1475 vmovl.s8 q1, d2 1476 1477 vld1.16 {q11}, [\src], \s_strd 1478 vext.8 d24, d22, d23, #2 1479 vext.8 d25, d22, d23, #4 1480 vext.8 d23, d22, d23, #6 1481 vmull.s16 q10, d22, d0[0] 1482 vmlal.s16 q10, d24, d0[1] 1483 vmlal.s16 q10, d25, d0[2] 1484 vmlal.s16 q10, d23, d0[3] 1485 vrshl.s32 q10, q10, q14 // -(6-intermediate_bits) 1486 vmovn.i32 d13, q10 1487 1488 bl L(\type\()_8tap_filter_4) 1489 vmov q7, q12 1490 bl L(\type\()_8tap_filter_4) 1491 vmov q8, q12 1492 bl L(\type\()_8tap_filter_4) 1493 vmov q9, q12 1494 149548: 1496 bl L(\type\()_8tap_filter_4) 1497 vmull.s16 q2, d13, d2[0] 1498 vmlal.s16 q2, d14, d2[1] 1499 vmlal.s16 q2, d15, d2[2] 1500 vmlal.s16 q2, d16, d2[3] 1501 vmlal.s16 q2, d17, d3[0] 1502 vmlal.s16 q2, d18, d3[1] 1503 vmlal.s16 q2, d19, d3[2] 1504 vmlal.s16 q2, d24, d3[3] 1505 vmull.s16 q3, d14, d2[0] 1506 vmlal.s16 q3, d15, d2[1] 1507 vmlal.s16 q3, d16, d2[2] 1508 vmlal.s16 q3, d17, d2[3] 1509 vmlal.s16 q3, d18, d3[0] 1510 vmlal.s16 q3, d19, d3[1] 1511 vmlal.s16 q3, d24, d3[2] 1512 vmlal.s16 q3, d25, d3[3] 1513.ifc \type, put 1514 vrshl.s32 q2, q2, q13 // -(6+intermediate_bits) 1515 vrshl.s32 q3, q3, q13 // -(6+intermediate_bits) 1516 vqmovun.s32 d4, q2 1517 vqmovun.s32 d5, q3 1518 vmin.u16 q2, q2, q15 1519.else 1520 vrshrn.i32 d4, q2, #6 1521 vrshrn.i32 d5, q3, #6 1522 vsub.i16 q2, q2, q13 // PREP_BIAS 1523.endif 1524 subs \h, \h, #2 1525 vst1.16 {d4}, [\dst, :64], \d_strd 1526 vst1.16 {d5}, [\ds2, :64], \d_strd 1527 ble 0f 1528 vmov d13, d15 1529 vmov q7, q8 1530 vmov q8, q9 1531 vmov q9, q12 1532 b 48b 15330: 1534 vpop {d13-d15} 1535 pop {r4-r11,pc} 1536 1537L(\type\()_8tap_filter_4): 1538 vld1.16 {q10}, [\sr2], \s_strd 1539 vld1.16 {q11}, [\src], \s_strd 1540 vext.8 d24, d20, d21, #2 1541 vext.8 d25, d20, d21, #4 1542 vext.8 d21, d20, d21, #6 1543 vmull.s16 q3, d20, d0[0] 1544 vmlal.s16 q3, d24, d0[1] 1545 vmlal.s16 q3, d25, d0[2] 1546 vmlal.s16 q3, d21, d0[3] 1547 vext.8 d24, d22, d23, #2 1548 vext.8 d25, d22, d23, #4 1549 vext.8 d23, d22, d23, #6 1550 vmull.s16 q10, d22, d0[0] 1551 vmlal.s16 q10, d24, d0[1] 1552 vmlal.s16 q10, d25, d0[2] 1553 vmlal.s16 q10, d23, d0[3] 1554 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 1555 vrshl.s32 q10, q10, q14 // -(6-intermediate_bits) 1556 vmovn.i32 d24, q3 1557 vmovn.i32 d25, q10 1558 bx lr 1559 156080: 1561160: 1562320: 1563 bgt 880f 1564 add \my, \my, #2 1565 vld1.8 {d0}, [\mx, :64] 1566 vld1.32 {d2[]}, [\my] 1567 sub \src, \src, #6 1568 sub \src, \src, \s_strd 1569 vmovl.s8 q0, d0 1570 vmovl.s8 q1, d2 1571 mov \my, \h 1572 1573164: // 8x2, 8x4, 16x2, 16x4, 32x2, 32x4 hv 1574 add \ds2, \dst, \d_strd 1575 add \sr2, \src, \s_strd 1576 lsl \d_strd, \d_strd, #1 1577 lsl \s_strd, \s_strd, #1 1578 1579 vld1.16 {q11, q12}, [\src], \s_strd 1580 vmull.s16 q2, d22, d0[0] 1581 vmull.s16 q3, d23, d0[0] 1582 vdup.32 q14, r12 // -(6-intermediate_bits) 1583.irpc i, 1234567 1584 vext.8 q10, q11, q12, #(2*\i) 1585.if \i < 4 1586 vmlal.s16 q2, d20, d0[\i] 1587 vmlal.s16 q3, d21, d0[\i] 1588.else 1589 vmlal.s16 q2, d20, d1[\i - 4] 1590 vmlal.s16 q3, d21, d1[\i - 4] 1591.endif 1592.endr 1593 vrshl.s32 q2, q2, q14 // -(6-intermediate_bits) 1594 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 1595 vmovn.i32 d16, q2 1596 vmovn.i32 d17, q3 1597 1598 bl L(\type\()_8tap_filter_8) 1599 vmov q9, q11 1600 vmov q10, q12 1601 16028: 1603 bl L(\type\()_8tap_filter_8) 1604 vmull.s16 q2, d16, d2[0] 1605 vmull.s16 q3, d17, d2[0] 1606 vmull.s16 q13, d18, d2[0] 1607 vmull.s16 q14, d19, d2[0] 1608.ifc \type, put 1609 vdup.32 q8, r8 // -(6+intermediate_bits) 1610.endif 1611 vmlal.s16 q2, d18, d2[1] 1612 vmlal.s16 q3, d19, d2[1] 1613 vmlal.s16 q13, d20, d2[1] 1614 vmlal.s16 q14, d21, d2[1] 1615 vmlal.s16 q2, d20, d2[2] 1616 vmlal.s16 q3, d21, d2[2] 1617 vmlal.s16 q13, d22, d2[2] 1618 vmlal.s16 q14, d23, d2[2] 1619 vmlal.s16 q2, d22, d2[3] 1620 vmlal.s16 q3, d23, d2[3] 1621 vmlal.s16 q13, d24, d2[3] 1622 vmlal.s16 q14, d25, d2[3] 1623.ifc \type, put 1624 vdup.16 q9, \bdmax // bitdepth_max 1625 vrshl.s32 q2, q2, q8 // -(6+intermediate_bits) 1626 vrshl.s32 q3, q3, q8 // -(6+intermediate_bits) 1627 vrshl.s32 q13, q13, q8 // -(6+intermediate_bits) 1628 vrshl.s32 q14, q14, q8 // -(6+intermediate_bits) 1629 vqmovun.s32 d4, q2 1630 vqmovun.s32 d5, q3 1631 vqmovun.s32 d6, q13 1632 vqmovun.s32 d7, q14 1633 vmin.u16 q2, q2, q15 1634 vmin.u16 q3, q3, q15 1635.else 1636 vmov.i16 q9, #PREP_BIAS 1637 vrshrn.i32 d4, q2, #6 1638 vrshrn.i32 d5, q3, #6 1639 vrshrn.i32 d6, q13, #6 1640 vrshrn.i32 d7, q14, #6 1641 vsub.i16 q2, q2, q9 // PREP_BIAS 1642 vsub.i16 q3, q3, q9 // PREP_BIAS 1643.endif 1644 subs \h, \h, #2 1645 vst1.16 {q2}, [\dst, :128], \d_strd 1646 vst1.16 {q3}, [\ds2, :128], \d_strd 1647 ble 9f 1648 vmov q8, q10 1649 vmov q9, q11 1650 vmov q10, q12 1651 b 8b 16529: 1653 subs \w, \w, #8 1654 ble 0f 1655 asr \s_strd, \s_strd, #1 1656 asr \d_strd, \d_strd, #1 1657 mls \src, \s_strd, \my, \src 1658 mls \dst, \d_strd, \my, \dst 1659 sub \src, \src, \s_strd, lsl #2 1660 mov \h, \my 1661 add \src, \src, #16 1662 add \dst, \dst, #16 1663 b 164b 16640: 1665 pop {r4-r11,pc} 1666 1667880: // 8x8, 8x16, ..., 16x8, ..., 32x8, ... hv 1668640: 16691280: 1670 vpush {q4-q7} 1671 vld1.8 {d0}, [\mx, :64] 1672 vld1.8 {d2}, [\my, :64] 1673 sub \src, \src, #6 1674 sub \src, \src, \s_strd 1675 sub \src, \src, \s_strd, lsl #1 1676 vmovl.s8 q0, d0 1677 vmovl.s8 q1, d2 1678 mov \my, \h 1679 1680168: 1681 add \ds2, \dst, \d_strd 1682 add \sr2, \src, \s_strd 1683 lsl \d_strd, \d_strd, #1 1684 lsl \s_strd, \s_strd, #1 1685 1686 vld1.16 {q11, q12}, [\src], \s_strd 1687 vmull.s16 q2, d22, d0[0] 1688 vmull.s16 q3, d23, d0[0] 1689 vdup.32 q14, r12 // -(6-intermediate_bits) 1690.irpc i, 1234567 1691 vext.8 q10, q11, q12, #(2*\i) 1692.if \i < 4 1693 vmlal.s16 q2, d20, d0[\i] 1694 vmlal.s16 q3, d21, d0[\i] 1695.else 1696 vmlal.s16 q2, d20, d1[\i - 4] 1697 vmlal.s16 q3, d21, d1[\i - 4] 1698.endif 1699.endr 1700 vrshl.s32 q2, q2, q14 // -(6-intermediate_bits) 1701 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 1702 vmovn.i32 d8, q2 1703 vmovn.i32 d9, q3 1704 1705 bl L(\type\()_8tap_filter_8) 1706 vmov q5, q11 1707 vmov q6, q12 1708 bl L(\type\()_8tap_filter_8) 1709 vmov q7, q11 1710 vmov q8, q12 1711 bl L(\type\()_8tap_filter_8) 1712 vmov q9, q11 1713 vmov q10, q12 1714 171588: 1716 bl L(\type\()_8tap_filter_8) 1717 vmull.s16 q2, d8, d2[0] 1718 vmull.s16 q3, d9, d2[0] 1719 vmull.s16 q13, d10, d2[0] 1720 vmull.s16 q14, d11, d2[0] 1721.ifc \type, put 1722 vdup.32 q4, r8 // -(6+intermediate_bits) 1723.endif 1724 vmlal.s16 q2, d10, d2[1] 1725 vmlal.s16 q3, d11, d2[1] 1726 vmlal.s16 q13, d12, d2[1] 1727 vmlal.s16 q14, d13, d2[1] 1728 vmlal.s16 q2, d12, d2[2] 1729 vmlal.s16 q3, d13, d2[2] 1730 vmlal.s16 q13, d14, d2[2] 1731 vmlal.s16 q14, d15, d2[2] 1732 vmlal.s16 q2, d14, d2[3] 1733 vmlal.s16 q3, d15, d2[3] 1734 vmlal.s16 q13, d16, d2[3] 1735 vmlal.s16 q14, d17, d2[3] 1736 vmlal.s16 q2, d16, d3[0] 1737 vmlal.s16 q3, d17, d3[0] 1738 vmlal.s16 q13, d18, d3[0] 1739 vmlal.s16 q14, d19, d3[0] 1740 vmlal.s16 q2, d18, d3[1] 1741 vmlal.s16 q3, d19, d3[1] 1742 vmlal.s16 q13, d20, d3[1] 1743 vmlal.s16 q14, d21, d3[1] 1744 vmlal.s16 q2, d20, d3[2] 1745 vmlal.s16 q3, d21, d3[2] 1746 vmlal.s16 q13, d22, d3[2] 1747 vmlal.s16 q14, d23, d3[2] 1748 vmlal.s16 q2, d22, d3[3] 1749 vmlal.s16 q3, d23, d3[3] 1750 vmlal.s16 q13, d24, d3[3] 1751 vmlal.s16 q14, d25, d3[3] 1752.ifc \type, put 1753 vrshl.s32 q2, q2, q4 // -(6+intermediate_bits) 1754 vrshl.s32 q3, q3, q4 // -(6+intermediate_bits) 1755 vrshl.s32 q13, q13, q4 // -(6+intermediate_bits) 1756 vrshl.s32 q14, q14, q4 // -(6+intermediate_bits) 1757 vqmovun.s32 d4, q2 1758 vqmovun.s32 d5, q3 1759 vqmovun.s32 d6, q13 1760 vqmovun.s32 d7, q14 1761 vmin.u16 q2, q2, q15 1762 vmin.u16 q3, q3, q15 1763.else 1764 vmov.i16 q5, #PREP_BIAS 1765 vrshrn.i32 d4, q2, #6 1766 vrshrn.i32 d5, q3, #6 1767 vrshrn.i32 d6, q13, #6 1768 vrshrn.i32 d7, q14, #6 1769 vsub.i16 q2, q2, q5 // PREP_BIAS 1770 vsub.i16 q3, q3, q5 // PREP_BIAS 1771.endif 1772 subs \h, \h, #2 1773 vst1.16 {q2}, [\dst, :128], \d_strd 1774 vst1.16 {q3}, [\ds2, :128], \d_strd 1775 ble 9f 1776 vmov q4, q6 1777 vmov q5, q7 1778 vmov q6, q8 1779 vmov q7, q9 1780 vmov q8, q10 1781 vmov q9, q11 1782 vmov q10, q12 1783 b 88b 17849: 1785 subs \w, \w, #8 1786 ble 0f 1787 asr \s_strd, \s_strd, #1 1788 asr \d_strd, \d_strd, #1 1789 mls \src, \s_strd, \my, \src 1790 mls \dst, \d_strd, \my, \dst 1791 sub \src, \src, \s_strd, lsl #3 1792 mov \h, \my 1793 add \src, \src, #16 1794 add \dst, \dst, #16 1795 b 168b 17960: 1797 vpop {q4-q7} 1798 pop {r4-r11,pc} 1799 1800L(\type\()_8tap_filter_8): 1801 vld1.16 {q13, q14}, [\sr2], \s_strd 1802 vmull.s16 q2, d26, d0[0] 1803 vmull.s16 q3, d27, d0[0] 1804.irpc i, 1234567 1805 vext.8 q12, q13, q14, #(2*\i) 1806.if \i < 4 1807 vmlal.s16 q2, d24, d0[\i] 1808 vmlal.s16 q3, d25, d0[\i] 1809.else 1810 vmlal.s16 q2, d24, d1[\i - 4] 1811 vmlal.s16 q3, d25, d1[\i - 4] 1812.endif 1813.endr 1814 vdup.32 q12, r12 // -(6-intermediate_bits) 1815 vld1.16 {q13, q14}, [\src], \s_strd 1816 vrshl.s32 q2, q2, q12 // -(6-intermediate_bits) 1817 vrshl.s32 q3, q3, q12 // -(6-intermediate_bits) 1818 vmovn.i32 d4, q2 1819 vmovn.i32 d5, q3 1820 1821 vmull.s16 q3, d26, d0[0] 1822 vmull.s16 q11, d27, d0[0] 1823.irpc i, 1234567 1824 vext.8 q12, q13, q14, #(2*\i) 1825.if \i < 4 1826 vmlal.s16 q3, d24, d0[\i] 1827 vmlal.s16 q11, d25, d0[\i] 1828.else 1829 vmlal.s16 q3, d24, d1[\i - 4] 1830 vmlal.s16 q11, d25, d1[\i - 4] 1831.endif 1832.endr 1833 vdup.32 q13, r12 // -(6-intermediate_bits) 1834 vrshl.s32 q3, q3, q13 // -(6-intermediate_bits) 1835 vrshl.s32 q11, q11, q13 // -(6-intermediate_bits) 1836 1837 vmovn.i32 d24, q3 1838 vmovn.i32 d25, q11 1839 vmov q11, q2 1840 bx lr 1841endfunc 1842 1843function \type\()_bilin_16bpc_neon, export=1 1844 push {r4-r11,lr} 1845 ldrd r4, r5, [sp, #36] 1846 ldrd r6, r7, [sp, #44] 1847.ifc \bdmax, r8 1848 ldr r8, [sp, #52] 1849.endif 1850 vdup.16 q1, \mx 1851 vdup.16 q3, \my 1852 rsb r9, \mx, #16 1853 rsb r10, \my, #16 1854 vdup.16 q0, r9 1855 vdup.16 q2, r10 1856.ifc \type, prep 1857 lsl \d_strd, \w, #1 1858.endif 1859 clz \bdmax, \bdmax // bitdepth_max 1860 clz r9, \w 1861 sub \bdmax, \bdmax, #18 // intermediate_bits = clz(bitdepth_max) - 18 1862 cmp \mx, #0 1863 sub r9, r9, #24 1864 rsb r11, \bdmax, #4 // 4 - intermediate_bits 1865 add r12, \bdmax, #4 // 4 + intermediate_bits 1866 bne L(\type\()_bilin_h) 1867 cmp \my, #0 1868 bne L(\type\()_bilin_v) 1869 b \type\()_neon 1870 1871L(\type\()_bilin_h): 1872 cmp \my, #0 1873 bne L(\type\()_bilin_hv) 1874 1875 adr r10, L(\type\()_bilin_h_tbl) 1876 vdup.16 q15, r11 // 4 - intermediate_bits 1877 ldr r9, [r10, r9, lsl #2] 1878 vneg.s16 q15, q15 // -(4-intermediate_bits) 1879.ifc \type, put 1880 vdup.16 q14, \bdmax // intermediate_bits 1881.else 1882 vmov.i16 q14, #PREP_BIAS 1883.endif 1884 add r10, r10, r9 1885.ifc \type, put 1886 vneg.s16 q14, q14 // -intermediate_bits 1887.endif 1888 bx r10 1889 1890 .align 2 1891L(\type\()_bilin_h_tbl): 1892 .word 1280f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 1893 .word 640f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 1894 .word 320f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 1895 .word 160f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 1896 .word 80f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 1897 .word 40f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 1898 .word 20f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 1899 190020: // 2xN h 1901.ifc \type, put 1902 add \ds2, \dst, \d_strd 1903 add \sr2, \src, \s_strd 1904 lsl \d_strd, \d_strd, #1 1905 lsl \s_strd, \s_strd, #1 19062: 1907 vld1.16 {d16}, [\src], \s_strd 1908 vld1.16 {d18}, [\sr2], \s_strd 1909 vext.8 d17, d16, d16, #2 1910 vext.8 d19, d18, d18, #2 1911 vtrn.32 d16, d18 1912 vtrn.32 d17, d19 1913 subs \h, \h, #2 1914 vmul.i16 d16, d16, d0 1915 vmla.i16 d16, d17, d2 1916 vrshl.u16 d16, d16, d30 1917 vrshl.u16 d16, d16, d28 1918 vst1.32 {d16[0]}, [\dst, :32], \d_strd 1919 vst1.32 {d16[1]}, [\ds2, :32], \d_strd 1920 bgt 2b 1921 pop {r4-r11,pc} 1922.endif 1923 192440: // 4xN h 1925 add \ds2, \dst, \d_strd 1926 add \sr2, \src, \s_strd 1927 lsl \d_strd, \d_strd, #1 1928 lsl \s_strd, \s_strd, #1 19294: 1930 vld1.16 {q8}, [\src], \s_strd 1931 vld1.16 {q10}, [\sr2], \s_strd 1932 vext.8 q9, q8, q8, #2 1933 vext.8 q11, q10, q10, #2 1934 vmov d17, d20 1935 vmov d19, d22 1936 subs \h, \h, #2 1937 vmul.i16 q8, q8, q0 1938 vmla.i16 q8, q9, q1 1939 vrshl.u16 q8, q8, q15 1940.ifc \type, put 1941 vrshl.u16 q8, q8, q14 1942.else 1943 vsub.i16 q8, q8, q14 1944.endif 1945 vst1.16 {d16}, [\dst, :64], \d_strd 1946 vst1.16 {d17}, [\ds2, :64], \d_strd 1947 bgt 4b 1948 pop {r4-r11,pc} 1949 195080: // 8xN h 1951 add \ds2, \dst, \d_strd 1952 add \sr2, \src, \s_strd 1953 lsl \d_strd, \d_strd, #1 1954 lsl \s_strd, \s_strd, #1 19558: 1956 vld1.16 {d16, d17, d18}, [\src], \s_strd 1957 vld1.16 {d20, d21, d22}, [\sr2], \s_strd 1958 vext.8 q9, q8, q9, #2 1959 vext.8 q11, q10, q11, #2 1960 subs \h, \h, #2 1961 vmul.i16 q8, q8, q0 1962 vmla.i16 q8, q9, q1 1963 vmul.i16 q10, q10, q0 1964 vmla.i16 q10, q11, q1 1965 vrshl.u16 q8, q8, q15 1966 vrshl.u16 q10, q10, q15 1967.ifc \type, put 1968 vrshl.u16 q8, q8, q14 1969 vrshl.u16 q10, q10, q14 1970.else 1971 vsub.i16 q8, q8, q14 1972 vsub.i16 q10, q10, q14 1973.endif 1974 vst1.16 {q8}, [\dst, :128], \d_strd 1975 vst1.16 {q10}, [\ds2, :128], \d_strd 1976 bgt 8b 1977 pop {r4-r11,pc} 1978160: 1979320: 1980640: 19811280: // 16xN, 32xN, ... h 1982 vpush {q4-q7} 1983 add \ds2, \dst, \d_strd 1984 add \sr2, \src, \s_strd 1985 lsl \s_strd, \s_strd, #1 1986 1987 sub \s_strd, \s_strd, \w, lsl #1 1988 sub \s_strd, \s_strd, #16 1989.ifc \type, put 1990 lsl \d_strd, \d_strd, #1 1991 sub \d_strd, \d_strd, \w, lsl #1 1992.endif 1993161: 1994 vld1.16 {q4}, [\src]! 1995 vld1.16 {q9}, [\sr2]! 1996 mov \mx, \w 1997 199816: 1999 vld1.16 {q5, q6}, [\src]! 2000 vld1.16 {q10, q11}, [\sr2]! 2001 vext.8 q7, q4, q5, #2 2002 vext.8 q8, q5, q6, #2 2003 vext.8 q12, q9, q10, #2 2004 vext.8 q13, q10, q11, #2 2005 vmul.i16 q4, q4, q0 2006 vmla.i16 q4, q7, q1 2007 vmul.i16 q5, q5, q0 2008 vmla.i16 q5, q8, q1 2009 vmul.i16 q9, q9, q0 2010 vmla.i16 q9, q12, q1 2011 vmul.i16 q10, q10, q0 2012 vmla.i16 q10, q13, q1 2013 vrshl.u16 q4, q4, q15 2014 vrshl.u16 q5, q5, q15 2015 vrshl.u16 q9, q9, q15 2016 vrshl.u16 q10, q10, q15 2017 subs \mx, \mx, #16 2018.ifc \type, put 2019 vrshl.u16 q4, q4, q14 2020 vrshl.u16 q5, q5, q14 2021 vrshl.u16 q9, q9, q14 2022 vrshl.u16 q10, q10, q14 2023.else 2024 vsub.i16 q4, q4, q14 2025 vsub.i16 q5, q5, q14 2026 vsub.i16 q9, q9, q14 2027 vsub.i16 q10, q10, q14 2028.endif 2029 vst1.16 {q4, q5}, [\dst, :128]! 2030 vst1.16 {q9, q10}, [\ds2, :128]! 2031 ble 9f 2032 2033 vmov q4, q6 2034 vmov q9, q11 2035 b 16b 2036 20379: 2038 add \dst, \dst, \d_strd 2039 add \ds2, \ds2, \d_strd 2040 add \src, \src, \s_strd 2041 add \sr2, \sr2, \s_strd 2042 2043 subs \h, \h, #2 2044 bgt 161b 2045 vpop {q4-q7} 2046 pop {r4-r11,pc} 2047 2048 2049L(\type\()_bilin_v): 2050 cmp \h, #4 2051 adr r10, L(\type\()_bilin_v_tbl) 2052.ifc \type, prep 2053 vdup.16 q15, r11 // 4 - intermediate_bits 2054.endif 2055 ldr r9, [r10, r9, lsl #2] 2056.ifc \type, prep 2057 vmov.i16 q14, #PREP_BIAS 2058 vneg.s16 q15, q15 // -(4-intermediate_bits) 2059.endif 2060 add r10, r10, r9 2061 bx r10 2062 2063 .align 2 2064L(\type\()_bilin_v_tbl): 2065 .word 1280f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2066 .word 640f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2067 .word 320f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2068 .word 160f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2069 .word 80f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2070 .word 40f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2071 .word 20f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2072 207320: // 2xN v 2074.ifc \type, put 2075 cmp \h, #2 2076 add \ds2, \dst, \d_strd 2077 add \sr2, \src, \s_strd 2078 lsl \s_strd, \s_strd, #1 2079 lsl \d_strd, \d_strd, #1 2080 2081 // 2x2 v 2082 vld1.32 {d16[]}, [\src], \s_strd 2083 bgt 24f 2084 vld1.32 {d17[]}, [\sr2], \s_strd 2085 vld1.32 {d18[]}, [\src], \s_strd 2086 vext.8 d16, d16, d17, #4 2087 vext.8 d17, d17, d18, #4 2088 vmul.i16 d16, d16, d4 2089 vmla.i16 d16, d17, d6 2090 vrshr.u16 d16, d16, #4 2091 vst1.32 {d16[0]}, [\dst, :32] 2092 vst1.32 {d16[1]}, [\ds2, :32] 2093 pop {r4-r11,pc} 209424: // 2x4, 2x8, ... v 2095 vld1.32 {d17[]}, [\sr2], \s_strd 2096 vld1.32 {d18[]}, [\src], \s_strd 2097 vld1.32 {d19[]}, [\sr2], \s_strd 2098 vld1.32 {d20[]}, [\src], \s_strd 2099 vext.8 d16, d16, d17, #4 2100 vext.8 d17, d17, d18, #4 2101 vext.8 d18, d18, d19, #4 2102 vext.8 d19, d19, d20, #4 2103 vswp d17, d18 2104 vmul.i16 q8, q8, q2 2105 vmla.i16 q8, q9, q3 2106 subs \h, \h, #4 2107 vrshr.u16 q8, q8, #4 2108 vst1.32 {d16[0]}, [\dst, :32], \d_strd 2109 vst1.32 {d16[1]}, [\ds2, :32], \d_strd 2110 vst1.32 {d17[0]}, [\dst, :32], \d_strd 2111 vst1.32 {d17[1]}, [\ds2, :32], \d_strd 2112 ble 0f 2113 vmov d16, d20 2114 b 24b 21150: 2116 pop {r4-r11,pc} 2117.endif 2118 211940: // 4xN v 2120 add \ds2, \dst, \d_strd 2121 add \sr2, \src, \s_strd 2122 lsl \s_strd, \s_strd, #1 2123 lsl \d_strd, \d_strd, #1 2124 vld1.16 {d16}, [\src], \s_strd 21254: 2126 vld1.16 {d17}, [\sr2], \s_strd 2127 vld1.16 {d19}, [\src], \s_strd 2128 vmov d18, d17 2129 vmul.i16 q8, q8, q2 2130 vmla.i16 q8, q9, q3 2131 subs \h, \h, #2 2132.ifc \type, put 2133 vrshr.u16 q8, q8, #4 2134.else 2135 vrshl.u16 q8, q8, q15 2136 vsub.i16 q8, q8, q14 2137.endif 2138 vst1.16 {d16}, [\dst, :64], \d_strd 2139 vst1.16 {d17}, [\ds2, :64], \d_strd 2140 ble 0f 2141 vmov d16, d19 2142 b 4b 21430: 2144 pop {r4-r11,pc} 2145 214680: // 8xN v 2147 add \ds2, \dst, \d_strd 2148 add \sr2, \src, \s_strd 2149 lsl \s_strd, \s_strd, #1 2150 lsl \d_strd, \d_strd, #1 2151 vld1.16 {q8}, [\src], \s_strd 21528: 2153 vld1.16 {q9}, [\sr2], \s_strd 2154 vld1.16 {q10}, [\src], \s_strd 2155 vmul.i16 q8, q8, q2 2156 vmla.i16 q8, q9, q3 2157 vmul.i16 q9, q9, q2 2158 vmla.i16 q9, q10, q3 2159 subs \h, \h, #2 2160.ifc \type, put 2161 vrshr.u16 q8, q8, #4 2162 vrshr.u16 q9, q9, #4 2163.else 2164 vrshl.u16 q8, q8, q15 2165 vrshl.u16 q9, q9, q15 2166 vsub.i16 q8, q8, q14 2167 vsub.i16 q9, q9, q14 2168.endif 2169 vst1.16 {q8}, [\dst, :128], \d_strd 2170 vst1.16 {q9}, [\ds2, :128], \d_strd 2171 ble 0f 2172 vmov q8, q10 2173 b 8b 21740: 2175 pop {r4-r11,pc} 2176 2177160: // 16xN, 32xN, ... 2178320: 2179640: 21801280: 2181 mov \my, \h 21821: 2183 add \ds2, \dst, \d_strd 2184 add \sr2, \src, \s_strd 2185 lsl \s_strd, \s_strd, #1 2186 lsl \d_strd, \d_strd, #1 2187 2188 vld1.16 {q8, q9}, [\src], \s_strd 21892: 2190 vld1.16 {q10, q11}, [\sr2], \s_strd 2191 vld1.16 {q12, q13}, [\src], \s_strd 2192 vmul.i16 q8, q8, q2 2193 vmla.i16 q8, q10, q3 2194 vmul.i16 q9, q9, q2 2195 vmla.i16 q9, q11, q3 2196 vmul.i16 q10, q10, q2 2197 vmla.i16 q10, q12, q3 2198 vmul.i16 q11, q11, q2 2199 vmla.i16 q11, q13, q3 2200 subs \h, \h, #2 2201.ifc \type, put 2202 vrshr.u16 q8, q8, #4 2203 vrshr.u16 q9, q9, #4 2204 vrshr.u16 q10, q10, #4 2205 vrshr.u16 q11, q11, #4 2206.else 2207 vrshl.u16 q8, q8, q15 2208 vrshl.u16 q9, q9, q15 2209 vrshl.u16 q10, q10, q15 2210 vrshl.u16 q11, q11, q15 2211 vsub.i16 q8, q8, q14 2212 vsub.i16 q9, q9, q14 2213 vsub.i16 q10, q10, q14 2214 vsub.i16 q11, q11, q14 2215.endif 2216 vst1.16 {q8, q9}, [\dst, :128], \d_strd 2217 vst1.16 {q10, q11}, [\ds2, :128], \d_strd 2218 ble 9f 2219 vmov q8, q12 2220 vmov q9, q13 2221 b 2b 22229: 2223 subs \w, \w, #16 2224 ble 0f 2225 asr \s_strd, \s_strd, #1 2226 asr \d_strd, \d_strd, #1 2227 mls \src, \s_strd, \my, \src 2228 mls \dst, \d_strd, \my, \dst 2229 sub \src, \src, \s_strd, lsl #1 2230 mov \h, \my 2231 add \src, \src, #32 2232 add \dst, \dst, #32 2233 b 1b 22340: 2235 pop {r4-r11,pc} 2236 2237L(\type\()_bilin_hv): 2238 adr r10, L(\type\()_bilin_hv_tbl) 2239 vdup.16 q15, r11 // 4 - intermediate_bits 2240 ldr r9, [r10, r9, lsl #2] 2241 vneg.s16 q15, q15 // -(4-intermediate_bits) 2242.ifc \type, put 2243 vdup.32 q14, r12 // 4 + intermediate_bits 2244.else 2245 vmov.i16 q14, #PREP_BIAS 2246.endif 2247 add r10, r10, r9 2248.ifc \type, put 2249 vneg.s32 q14, q14 // -(4+intermediate_bits) 2250.endif 2251 bx r10 2252 2253 .align 2 2254L(\type\()_bilin_hv_tbl): 2255 .word 1280f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2256 .word 640f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2257 .word 320f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2258 .word 160f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2259 .word 80f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2260 .word 40f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2261 .word 20f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2262 226320: // 2xN hv 2264.ifc \type, put 2265 add \sr2, \src, \s_strd 2266 add \ds2, \dst, \d_strd 2267 lsl \s_strd, \s_strd, #1 2268 lsl \d_strd, \d_strd, #1 2269 2270 vld1.16 {d20}, [\src], \s_strd 2271 vext.8 d21, d20, d20, #2 2272 vmul.i16 d16, d20, d0 2273 vmla.i16 d16, d21, d2 2274 vrshl.u16 d16, d16, d30 2275 vext.8 d16, d16, d16, #4 2276 22772: 2278 vld1.16 {d20}, [\sr2], \s_strd 2279 vld1.16 {d22}, [\src], \s_strd 2280 vext.8 d21, d20, d20, #2 2281 vext.8 d23, d22, d22, #2 2282 vtrn.32 d20, d22 2283 vtrn.32 d21, d23 2284 vmul.i16 d18, d20, d0 2285 vmla.i16 d18, d21, d2 2286 vrshl.u16 d18, d18, d30 2287 2288 vext.8 d16, d16, d18, #4 2289 2290 vmull.u16 q8, d16, d4 2291 vmlal.u16 q8, d18, d6 2292 vrshl.u32 q8, q8, q14 2293 vmovn.i32 d16, q8 2294 subs \h, \h, #2 2295 vst1.32 {d16[0]}, [\dst, :32], \d_strd 2296 vst1.32 {d16[1]}, [\ds2, :32], \d_strd 2297 ble 0f 2298 vmov d16, d18 2299 b 2b 23000: 2301 pop {r4-r11,pc} 2302.endif 2303 230440: // 4xN hv 2305 add \sr2, \src, \s_strd 2306 add \ds2, \dst, \d_strd 2307 lsl \s_strd, \s_strd, #1 2308 lsl \d_strd, \d_strd, #1 2309 2310 vld1.16 {q10}, [\src], \s_strd 2311 vext.8 d21, d20, d21, #2 2312 vmul.i16 d16, d20, d0 2313 vmla.i16 d16, d21, d2 2314 vrshl.u16 d16, d16, d30 2315 23164: 2317 vld1.16 {q10}, [\sr2], \s_strd 2318 vld1.16 {q11}, [\src], \s_strd 2319 vext.8 d21, d20, d21, #2 2320 vext.8 d23, d22, d23, #2 2321 vswp d21, d22 2322 vmul.i16 q9, q10, q0 2323 vmla.i16 q9, q11, q1 2324 vrshl.u16 q9, q9, q15 2325 2326 vmull.u16 q10, d16, d4 2327 vmlal.u16 q10, d18, d6 2328 vmull.u16 q11, d18, d4 2329 vmlal.u16 q11, d19, d6 2330.ifc \type, put 2331 vrshl.u32 q10, q10, q14 2332 vrshl.u32 q11, q11, q14 2333 vmovn.i32 d20, q10 2334 vmovn.i32 d21, q11 2335.else 2336 vrshrn.i32 d20, q10, #4 2337 vrshrn.i32 d21, q11, #4 2338 vsub.i16 q10, q10, q14 2339.endif 2340 subs \h, \h, #2 2341 vst1.16 {d20}, [\dst, :64], \d_strd 2342 vst1.16 {d21}, [\ds2, :64], \d_strd 2343 ble 0f 2344 vmov d16, d19 2345 b 4b 23460: 2347 pop {r4-r11,pc} 2348 234980: // 8xN, 16xN, ... hv 2350160: 2351320: 2352640: 23531280: 2354 mov \my, \h 2355 23561: 2357 add \sr2, \src, \s_strd 2358 add \ds2, \dst, \d_strd 2359 lsl \s_strd, \s_strd, #1 2360 lsl \d_strd, \d_strd, #1 2361 2362 vld1.16 {d20, d21, d22}, [\src], \s_strd 2363 vext.8 q11, q10, q11, #2 2364 vmul.i16 q8, q10, q0 2365 vmla.i16 q8, q11, q1 2366 vrshl.u16 q8, q8, q15 2367 23682: 2369 vld1.16 {d20, d21, d22}, [\sr2], \s_strd 2370 vld1.16 {d24, d25, d26}, [\src], \s_strd 2371 vext.8 q11, q10, q11, #2 2372 vext.8 q13, q12, q13, #2 2373 vmul.i16 q9, q10, q0 2374 vmla.i16 q9, q11, q1 2375 vmul.i16 q10, q12, q0 2376 vmla.i16 q10, q13, q1 2377 vrshl.u16 q9, q9, q15 2378 vrshl.u16 q10, q10, q15 2379 2380 vmull.u16 q11, d16, d4 2381 vmlal.u16 q11, d18, d6 2382 vmull.u16 q12, d17, d4 2383 vmlal.u16 q12, d19, d6 2384 vmull.u16 q8, d18, d4 2385 vmlal.u16 q8, d20, d6 2386 vmull.u16 q9, d19, d4 2387 vmlal.u16 q9, d21, d6 2388.ifc \type, put 2389 vrshl.u32 q11, q11, q14 2390 vrshl.u32 q12, q12, q14 2391 vrshl.u32 q8, q8, q14 2392 vrshl.u32 q9, q9, q14 2393 vmovn.i32 d22, q11 2394 vmovn.i32 d23, q12 2395 vmovn.i32 d16, q8 2396 vmovn.i32 d17, q9 2397.else 2398 vrshrn.i32 d22, q11, #4 2399 vrshrn.i32 d23, q12, #4 2400 vrshrn.i32 d16, q8, #4 2401 vrshrn.i32 d17, q9, #4 2402 vsub.i16 q11, q11, q14 2403 vsub.i16 q8, q8, q14 2404.endif 2405 subs \h, \h, #2 2406 vst1.16 {q11}, [\dst, :128], \d_strd 2407 vst1.16 {q8}, [\ds2, :128], \d_strd 2408 ble 9f 2409 vmov q8, q10 2410 b 2b 24119: 2412 subs \w, \w, #8 2413 ble 0f 2414 asr \s_strd, \s_strd, #1 2415 asr \d_strd, \d_strd, #1 2416 mls \src, \s_strd, \my, \src 2417 mls \dst, \d_strd, \my, \dst 2418 sub \src, \src, \s_strd, lsl #1 2419 mov \h, \my 2420 add \src, \src, #16 2421 add \dst, \dst, #16 2422 b 1b 24230: 2424 pop {r4-r11,pc} 2425endfunc 2426.endm 2427 2428filter_fn put, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 2429filter_fn prep, r0, r8, r1, r2, r3, r4, r5, r6, r7, r9, r10 2430 2431.macro load_filter_ptr src 2432 asr r12, \src, #10 2433 add r12, r11, r12, lsl #3 2434.endm 2435 2436.macro load_filter_coef dst, src, inc 2437 vld1.8 {\dst}, [r12, :64] 2438 add \src, \src, \inc 2439.endm 2440 2441.macro load_filter_row dst, src, inc 2442 load_filter_ptr \src 2443 load_filter_coef \dst, \src, \inc 2444.endm 2445 2446function warp_filter_horz_neon 2447 load_filter_ptr r5 // filter 0 2448 vld1.16 {q6,q7}, [r2], r3 2449 2450 load_filter_coef d0, r5, r7 // filter 0 2451 load_filter_row d2, r5, r7 // filter 1 2452 vmovl.s8 q0, d0 // filter 0 2453 vext.8 q3, q6, q7, #2*1 // filter 1 pixels 2454 vmovl.s8 q1, d2 // filter 1 2455 2456 vmull.s16 q4, d12, d0 // filter 0 output (0-3) 2457 vmull.s16 q5, d13, d1 // filter 0 output (4-7) 2458 2459 load_filter_ptr r5 // filter 2 2460 2461 vmull.s16 q2, d6, d2 // filter 1 output (0-3) 2462 vmull.s16 q3, d7, d3 // filter 1 output (4-7) 2463 2464 load_filter_coef d0, r5, r7 // filter 2 2465 2466 vpadd.i32 d8, d8, d9 // half pixel 0 (2x32) 2467 vpadd.i32 d9, d10, d11 // half pixel 0 (2x32) 2468 2469 load_filter_ptr r5 // filter 3 2470 2471 vpadd.i32 d4, d4, d5 // half pixel 1 (2x32) 2472 vpadd.i32 d5, d6, d7 // half pixel 1 (2x32) 2473 2474 vmovl.s8 q0, d0 // filter 2 2475 vext.8 q3, q6, q7, #2*2 // filter 2 pixels 2476 2477 vpadd.i32 d8, d8, d9 // pixel 0 (2x32) 2478 vpadd.i32 d9, d4, d5 // pixel 1 (2x32) 2479 2480 load_filter_coef d2, r5, r7 // filter 3 2481 2482 vmull.s16 q2, d6, d0 // filter 2 output (0-3) 2483 vmull.s16 q3, d7, d1 // filter 2 output (4-7) 2484 2485 load_filter_ptr r5 // filter 4 2486 2487 vpadd.i32 d8, d8, d9 // pixel 0,1 2488 2489 vpadd.i32 d9, d4, d5 // half pixel 2 (2x32) 2490 vpadd.i32 d10, d6, d7 // half pixel 2 (2x32) 2491 2492 vmovl.s8 q1, d2 // filter 3 2493 vext.8 q3, q6, q7, #2*3 // filter 3 pixels 2494 2495 load_filter_coef d0, r5, r7 // filter 4 2496 2497 vpadd.i32 d9, d9, d10 // pixel 2 (2x32) 2498 2499 vmull.s16 q2, d6, d2 // filter 3 output (0-3) 2500 vmull.s16 q3, d7, d3 // filter 3 output (4-7) 2501 2502 vmovl.s8 q0, d0 // filter 4 2503 load_filter_ptr r5 // filter 5 2504 2505 vpadd.i32 d10, d4, d5 // half pixel 3 (2x32) 2506 vpadd.i32 d11, d6, d7 // half pixel 3 (2x32) 2507 2508 vext.8 q3, q6, q7, #2*4 // filter 4 pixels 2509 load_filter_coef d2, r5, r7 // filter 5 2510 2511 vpadd.i32 d10, d10, d11 // pixel 3 (2x32) 2512 2513 vpadd.i32 d9, d9, d10 // pixel 2,3 2514 2515 vmull.s16 q2, d6, d0 // filter 4 output (0-3) 2516 vmull.s16 q3, d7, d1 // filter 4 output (4-7) 2517 2518 vmovl.s8 q1, d2 // filter 5 2519 load_filter_ptr r5 // filter 6 2520 2521 vpadd.i32 d10, d4, d5 // half pixel 4 (2x32) 2522 vpadd.i32 d11, d6, d7 // half pixel 4 (2x32) 2523 2524 vext.8 q3, q6, q7, #2*5 // filter 5 pixels 2525 load_filter_coef d0, r5, r7 // filter 6 2526 2527 vpadd.i32 d10, d10, d11 // pixel 4 (2x32) 2528 2529 vmull.s16 q2, d6, d2 // filter 5 output (0-3) 2530 vmull.s16 q3, d7, d3 // filter 5 output (4-7) 2531 2532 vmovl.s8 q0, d0 // filter 6 2533 load_filter_ptr r5 // filter 7 2534 2535 vpadd.i32 d4, d4, d5 // half pixel 5 (2x32) 2536 vpadd.i32 d5, d6, d7 // half pixel 5 (2x32) 2537 2538 vext.8 q3, q6, q7, #2*6 // filter 6 pixels 2539 load_filter_coef d2, r5, r7 // filter 7 2540 2541 vpadd.i32 d11, d4, d5 // pixel 5 (2x32) 2542 2543 vmull.s16 q2, d6, d0 // filter 6 output (0-3) 2544 vmull.s16 q3, d7, d1 // filter 6 output (4-7) 2545 2546 vmovl.s8 q1, d2 // filter 7 2547 2548 vpadd.i32 d10, d10, d11 // pixel 4,5 2549 2550 vpadd.i32 d4, d4, d5 // half pixel 6 (2x32) 2551 vpadd.i32 d5, d6, d7 // half pixel 6 (2x32) 2552 2553 vext.8 q3, q6, q7, #2*7 // filter 7 pixels 2554 2555 vpadd.i32 d11, d4, d5 // pixel 6 (2x32) 2556 2557 vmull.s16 q2, d6, d2 // filter 7 output (0-3) 2558 vmull.s16 q3, d7, d3 // filter 7 output (4-7) 2559 2560 vld1.32 {d14[],d15[]}, [sp] // -(7 - intermediate_bits) 2561 2562 vpadd.i32 d4, d4, d5 // half pixel 7 (2x32) 2563 vpadd.i32 d5, d6, d7 // half pixel 7 (2x32) 2564 2565 sub r5, r5, r7, lsl #3 2566 2567 vpadd.i32 d4, d4, d5 // pixel 7 (2x32) 2568 2569 add r5, r5, r8 2570 2571 vpadd.i32 d11, d11, d4 // pixel 6,7 2572 2573 vrshl.s32 q4, q4, q7 // -(7 - intermediate_bits) 2574 vrshl.s32 q5, q5, q7 // -(7 - intermediate_bits) 2575 2576 bx lr 2577endfunc 2578 2579// void dav1d_warp_affine_8x8_16bpc_neon( 2580// pixel *dst, const ptrdiff_t dst_stride, 2581// const pixel *src, const ptrdiff_t src_stride, 2582// const int16_t *const abcd, int mx, int my, 2583// const int bitdepth_max) 2584.macro warp t 2585function warp_affine_8x8\t\()_16bpc_neon, export=1 2586 push {r4-r11,lr} 2587 vpush {q4-q7} 2588 ldrd r4, r5, [sp, #100] 2589 ldrd r6, r7, [sp, #108] 2590 sub sp, sp, #8 2591 2592 clz r7, r7 2593 // intermediate_bits = clz(bitdepth_max) - 18 2594.ifb \t 2595 sub r8, r7, #11 // 7 + intermediate_bits = clz(bitdepth_max) - 18 + 7 2596.endif 2597 sub r7, r7, #25 // -(7 - intermediate_bits) 2598.ifb \t 2599 neg r8, r8 // -(7 + intermediate_bits) 2600.endif 2601 str r7, [sp] // spill -(7 - intermediate_bits) on stack 2602.ifb \t 2603 str r8, [sp, #4] // spill -(7 + intermediate_bits) on stack 2604.endif 2605 2606 ldrd r8, r9, [r4] 2607 sxth r7, r8 2608 asr r8, r8, #16 2609 asr r4, r9, #16 2610 sxth r9, r9 2611 mov r10, #8 2612 sub r2, r2, r3, lsl #1 2613 sub r2, r2, r3 2614 sub r2, r2, #6 2615 movrel r11, X(mc_warp_filter), 64*8 2616.ifnb \t 2617 lsl r1, r1, #1 2618.endif 2619 add r5, r5, #512 2620 add r6, r6, #512 2621 2622 bl warp_filter_horz_neon 2623 vmovn.i32 d16, q4 2624 vmovn.i32 d17, q5 2625 bl warp_filter_horz_neon 2626 vmovn.i32 d18, q4 2627 vmovn.i32 d19, q5 2628 bl warp_filter_horz_neon 2629 vmovn.i32 d20, q4 2630 vmovn.i32 d21, q5 2631 bl warp_filter_horz_neon 2632 vmovn.i32 d22, q4 2633 vmovn.i32 d23, q5 2634 bl warp_filter_horz_neon 2635 vmovn.i32 d24, q4 2636 vmovn.i32 d25, q5 2637 bl warp_filter_horz_neon 2638 vmovn.i32 d26, q4 2639 vmovn.i32 d27, q5 2640 bl warp_filter_horz_neon 2641 vmovn.i32 d28, q4 2642 vmovn.i32 d29, q5 2643 26441: 2645 bl warp_filter_horz_neon 2646 vmovn.i32 d30, q4 2647 vmovn.i32 d31, q5 2648 2649 load_filter_row d8, r6, r9 2650 load_filter_row d9, r6, r9 2651 load_filter_row d10, r6, r9 2652 load_filter_row d11, r6, r9 2653 load_filter_row d12, r6, r9 2654 load_filter_row d13, r6, r9 2655 load_filter_row d14, r6, r9 2656 load_filter_row d15, r6, r9 2657 transpose_8x8b q4, q5, q6, q7, d8, d9, d10, d11, d12, d13, d14, d15 2658 vmovl.s8 q1, d8 2659 vmovl.s8 q2, d9 2660 vmovl.s8 q3, d10 2661 vmovl.s8 q4, d11 2662 vmovl.s8 q5, d12 2663 vmovl.s8 q6, d13 2664 2665 sub r6, r6, r9, lsl #3 2666 2667 // This ordering of vmull/vmlal is highly beneficial for 2668 // Cortex A8/A9/A53 here, but harmful for Cortex A7. 2669 vmull.s16 q0, d16, d2 2670 vmlal.s16 q0, d18, d4 2671 vmlal.s16 q0, d20, d6 2672 vmlal.s16 q0, d22, d8 2673 vmlal.s16 q0, d24, d10 2674 vmlal.s16 q0, d26, d12 2675 vmull.s16 q1, d17, d3 2676 vmlal.s16 q1, d19, d5 2677 vmlal.s16 q1, d21, d7 2678 vmlal.s16 q1, d23, d9 2679 vmlal.s16 q1, d25, d11 2680 vmlal.s16 q1, d27, d13 2681 2682 vmovl.s8 q2, d14 2683 vmovl.s8 q3, d15 2684 2685 vmlal.s16 q0, d28, d4 2686 vmlal.s16 q0, d30, d6 2687 vmlal.s16 q1, d29, d5 2688 vmlal.s16 q1, d31, d7 2689 2690.ifb \t 2691 ldr lr, [sp, #4] // -(7 + intermediate_bits) 2692 ldr r12, [sp, #120] // bitdepth_max 2693 vdup.32 q2, lr // -(7 + intermediate_bits) 2694 vdup.16 q3, r12 // bitdepth_max 2695.endif 2696 2697 vmov q8, q9 2698 vmov q9, q10 2699.ifb \t 2700 vrshl.s32 q0, q0, q2 // -(7 + intermediate_bits) 2701 vrshl.s32 q1, q1, q2 // -(7 + intermediate_bits) 2702.else 2703 vrshrn.s32 d0, q0, #7 2704 vrshrn.s32 d1, q1, #7 2705 vmov.i16 q3, #PREP_BIAS 2706.endif 2707 vmov q10, q11 2708.ifb \t 2709 vqmovun.s32 d0, q0 2710 vqmovun.s32 d1, q1 2711.else 2712 vsub.i16 q0, q0, q3 // PREP_BIAS 2713.endif 2714 vmov q11, q12 2715 vmov q12, q13 2716.ifb \t 2717 vmin.u16 q0, q0, q3 // bitdepth_max 2718.endif 2719 vmov q13, q14 2720 vmov q14, q15 2721 subs r10, r10, #1 2722 vst1.16 {q0}, [r0, :128], r1 2723 2724 add r6, r6, r4 2725 bgt 1b 2726 2727 add sp, sp, #8 2728 vpop {q4-q7} 2729 pop {r4-r11,pc} 2730endfunc 2731.endm 2732 2733warp 2734warp t 2735