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 ldrd r4, r5, [sp, #20] 127 ldr r6, [sp, #28] 128 clz r4, r4 129.ifnc \type, avg 130 ldr r7, [sp, #32] 131 vmov.i16 q14, #0 132 vdup.16 q15, r7 // bitdepth_max 133.endif 134.ifc \type, w_avg 135 vpush {q4} 136.endif 137.ifc \type, mask 138 vpush {q4-q7} 139.endif 140 clz r7, \bdmax 141 sub r7, r7, #18 // intermediate_bits = clz(bitdepth_max) - 18 142.ifc \type, avg 143 mov lr, #1 144 movw r12, #2*PREP_BIAS 145 lsl lr, lr, r7 // 1 << intermediate_bits 146 neg r12, r12 // -2*PREP_BIAS 147 add r7, r7, #1 148 sub r12, r12, lr // -2*PREP_BIAS - 1 << intermediate_bits 149 neg r7, r7 // -(intermediate_bits+1) 150 vdup.16 q12, r12 // -2*PREP_BIAS - 1 << intermediate_bits 151 vdup.16 q13, r7 // -(intermediate_bits+1) 152.else 153 mov r12, #PREP_BIAS 154 lsr r12, r12, r7 // PREP_BIAS >> intermediate_bits 155 neg r7, r7 // -intermediate_bits 156 vdup.16 q12, r12 // PREP_BIAS >> intermediate_bits 157 vdup.16 q13, r7 // -intermediate_bits 158.endif 159.ifc \type, w_avg 160 vdup.32 q4, r6 161 vneg.s32 q4, q4 162.endif 163 adr r7, L(\type\()_tbl) 164 sub r4, r4, #24 165 \type q8, d16, d17, q9, d18, d19 166 ldr r4, [r7, r4, lsl #2] 167 add r7, r7, r4 168 bx r7 169 170 .align 2 171L(\type\()_tbl): 172 .word 1280f - L(\type\()_tbl) + CONFIG_THUMB 173 .word 640f - L(\type\()_tbl) + CONFIG_THUMB 174 .word 320f - L(\type\()_tbl) + CONFIG_THUMB 175 .word 160f - L(\type\()_tbl) + CONFIG_THUMB 176 .word 80f - L(\type\()_tbl) + CONFIG_THUMB 177 .word 40f - L(\type\()_tbl) + CONFIG_THUMB 178 17940: 180 add r7, r0, r1 181 lsl r1, r1, #1 1824: 183 subs r5, r5, #4 184 vst1.16 {d16}, [r0, :64], r1 185 vst1.16 {d17}, [r7, :64], r1 186 vst1.16 {d18}, [r0, :64], r1 187 vst1.16 {d19}, [r7, :64], r1 188 ble 0f 189 \type q8, d16, d17, q9, d18, d19 190 b 4b 19180: 192 add r7, r0, r1 193 lsl r1, r1, #1 1948: 195 vst1.16 {q8}, [r0, :128], r1 196 subs r5, r5, #2 197 vst1.16 {q9}, [r7, :128], r1 198 ble 0f 199 \type q8, d16, d17, q9, d18, d19 200 b 8b 201160: 20216: 203 \type q10, d20, d21, q11, d22, d23 204 vst1.16 {q8, q9}, [r0, :128], r1 205 subs r5, r5, #2 206 vst1.16 {q10, q11}, [r0, :128], r1 207 ble 0f 208 \type q8, d16, d17, q9, d18, d19 209 b 16b 210320: 211 add r7, r0, #32 21232: 213 \type q10, d20, d21, q11, d22, d23 214 vst1.16 {q8, q9}, [r0, :128], r1 215 subs r5, r5, #1 216 vst1.16 {q10, q11}, [r7, :128], r1 217 ble 0f 218 \type q8, d16, d17, q9, d18, d19 219 b 32b 220640: 221 add r7, r0, #32 222 mov r12, #64 223 sub r1, r1, #64 22464: 225 \type q10, d20, d21, q11, d22, d23 226 vst1.16 {q8, q9}, [r0, :128], r12 227 \type q8, d16, d17, q9, d18, d19 228 vst1.16 {q10, q11}, [r7, :128], r12 229 \type q10, d20, d21, q11, d22, d23 230 vst1.16 {q8, q9}, [r0, :128], r1 231 subs r5, r5, #1 232 vst1.16 {q10, q11}, [r7, :128], r1 233 ble 0f 234 \type q8, d16, d17, q9, d18, d19 235 b 64b 2361280: 237 add r7, r0, #32 238 mov r12, #64 239 sub r1, r1, #192 240128: 241 \type q10, d20, d21, q11, d22, d23 242 vst1.16 {q8, q9}, [r0, :128], r12 243 \type q8, d16, d17, q9, d18, d19 244 vst1.16 {q10, q11}, [r7, :128], r12 245 \type q10, d20, d21, q11, d22, d23 246 vst1.16 {q8, q9}, [r0, :128], r12 247 \type q8, d16, d17, q9, d18, d19 248 vst1.16 {q10, q11}, [r7, :128], r12 249 \type q10, d20, d21, q11, d22, d23 250 vst1.16 {q8, q9}, [r0, :128], r12 251 \type q8, d16, d17, q9, d18, d19 252 vst1.16 {q10, q11}, [r7, :128], r12 253 \type q10, d20, d21, q11, d22, d23 254 vst1.16 {q8, q9}, [r0, :128], r1 255 subs r5, r5, #1 256 vst1.16 {q10, q11}, [r7, :128], r1 257 ble 0f 258 \type q8, d16, d17, q9, d18, d19 259 b 128b 2600: 261.ifc \type, mask 262 vpop {q4-q7} 263.endif 264.ifc \type, w_avg 265 vpop {q4} 266.endif 267 pop {r4-r7,pc} 268endfunc 269.endm 270 271bidir_fn avg, r6 272bidir_fn w_avg, r7 273bidir_fn mask, r7 274 275 276.macro w_mask_fn type 277function w_mask_\type\()_16bpc_neon, export=1 278 push {r4-r10,lr} 279 vpush {q4-q7} 280 ldrd r4, r5, [sp, #96] 281 ldrd r6, r7, [sp, #104] 282 ldr r8, [sp, #112] 283 clz r9, r4 284 adr lr, L(w_mask_\type\()_tbl) 285 vdup.16 q15, r8 // bitdepth_max 286 sub r9, r9, #24 287 clz r8, r8 // clz(bitdepth_max) 288 ldr r9, [lr, r9, lsl #2] 289 add r9, lr, r9 290 sub r8, r8, #12 // sh = intermediate_bits + 6 = clz(bitdepth_max) - 12 291 mov r10, #PREP_BIAS*64 292 neg r8, r8 // -sh 293 movw r12, #27615 // (64 + 1 - 38)<<mask_sh - 1 - mask_rnd 294 vdup.32 q14, r8 // -sh 295 vdup.16 q0, r12 296.if \type == 444 297 vmov.i8 q1, #64 298.elseif \type == 422 299 vdup.8 d4, r7 300 vmov.i8 d2, #129 301 vsub.i16 d2, d2, d4 302.elseif \type == 420 303 vdup.16 q2, r7 304 vmov.i16 q1, #0x100 305 vsub.i16 q1, q1, q2 306.endif 307 add r12, r0, r1 308 lsl r1, r1, #1 309 bx r9 310 311 .align 2 312L(w_mask_\type\()_tbl): 313 .word 1280f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 314 .word 640f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 315 .word 320f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 316 .word 160f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 317 .word 8f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 318 .word 4f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 319 3204: 321 vld1.16 {q2, q3}, [r2, :128]! // tmp1 (four rows at once) 322 vld1.16 {q4, q5}, [r3, :128]! // tmp2 (four rows at once) 323 subs r5, r5, #4 324 vdup.32 q13, r10 // PREP_BIAS*64 325 vabd.s16 q6, q2, q4 // abs(tmp1 - tmp2) 326 vabd.s16 q7, q3, q5 327 vsubl.s16 q8, d8, d4 // tmp2 - tmp1 (requires 17 bit) 328 vsubl.s16 q9, d9, d5 329 vsubl.s16 q10, d10, d6 330 vsubl.s16 q11, d11, d7 331 vqsub.u16 q6, q0, q6 // 27615 - abs() 332 vqsub.u16 q7, q0, q7 333 vshll.s16 q5, d7, #6 // tmp1 << 6 334 vshll.s16 q4, d6, #6 335 vshll.s16 q3, d5, #6 336 vshll.s16 q2, d4, #6 337 vshr.u16 q6, q6, #10 // 64-m = (27615 - abs()) >> mask_sh 338 vshr.u16 q7, q7, #10 339 vadd.i32 q2, q2, q13 // += PREP_BIAS*64 340 vadd.i32 q3, q3, q13 341 vadd.i32 q4, q4, q13 342 vadd.i32 q5, q5, q13 343 vmovl.u16 q12, d12 344 vmovl.u16 q13, d13 345 vmla.i32 q2, q8, q12 // (tmp2-tmp1)*(64-m) 346 vmovl.u16 q12, d14 347 vmla.i32 q3, q9, q13 348 vmovl.u16 q13, d15 349 vmla.i32 q4, q10, q12 350 vmla.i32 q5, q11, q13 351 vrshl.s32 q2, q2, q14 // (tmp1<<6 + (tmp2-tmp1)*(64-m) + (1 << (sh-1)) + PREP_BIAS*64) >> sh 352 vrshl.s32 q3, q3, q14 353 vrshl.s32 q4, q4, q14 354 vrshl.s32 q5, q5, q14 355 vqmovun.s32 d4, q2 // iclip_pixel 356 vqmovun.s32 d5, q3 357 vqmovun.s32 d6, q4 358 vqmovun.s32 d7, q5 359 vmin.u16 q2, q2, q15 // iclip_pixel 360 vmin.u16 q3, q3, q15 // iclip_pixel 361.if \type == 444 362 vmovn.i16 d12, q6 // 64 - m 363 vmovn.i16 d13, q7 364 vsub.i16 q6, q1, q6 // m 365 vst1.8 {q6}, [r6, :128]! 366.elseif \type == 422 367 vpadd.i16 d12, d12, d13 // (64 - m) + (64 - n) (column wise addition) 368 vpadd.i16 d13, d14, d15 369 vmovn.i16 d12, q6 370 vhsub.u8 d12, d2, d12 // ((129 - sign) - ((64 - m) + (64 - n)) >> 1 371 vst1.8 {d12}, [r6, :64]! 372.elseif \type == 420 373 vadd.i16 d12, d12, d13 // (64 - my1) + (64 - my2) (row wise addition) 374 vadd.i16 d13, d14, d15 375 vpadd.i16 d12, d12, d13 // (128 - m) + (128 - n) (column wise addition) 376 vsub.i16 d12, d2, d12 // (256 - sign) - ((128 - m) + (128 - n)) 377 vrshrn.i16 d12, q6, #2 // ((256 - sign) - ((128 - m) + (128 - n)) + 2) >> 2 378 vst1.32 {d12[0]}, [r6, :32]! 379.endif 380 vst1.16 {d4}, [r0, :64], r1 381 vst1.16 {d5}, [r12, :64], r1 382 vst1.16 {d6}, [r0, :64], r1 383 vst1.16 {d7}, [r12, :64], r1 384 bgt 4b 385 vpop {q4-q7} 386 pop {r4-r10,pc} 3878: 388 vld1.16 {q2, q3}, [r2, :128]! // tmp1 389 vld1.16 {q4, q5}, [r3, :128]! // tmp2 390 subs r5, r5, #2 391 vdup.32 q13, r10 // PREP_BIAS*64 392 vabd.s16 q6, q2, q4 // abs(tmp1 - tmp2) 393 vabd.s16 q7, q3, q5 394 vsubl.s16 q8, d8, d4 // tmp2 - tmp1 (requires 17 bit) 395 vsubl.s16 q9, d9, d5 396 vsubl.s16 q10, d10, d6 397 vsubl.s16 q11, d11, d7 398 vqsub.u16 q6, q0, q6 // 27615 - abs() 399 vqsub.u16 q7, q0, q7 400 vshll.s16 q5, d7, #6 // tmp1 << 6 401 vshll.s16 q4, d6, #6 402 vshll.s16 q3, d5, #6 403 vshll.s16 q2, d4, #6 404 vshr.u16 q6, q6, #10 // 64-m = (27615 - abs()) >> mask_sh 405 vshr.u16 q7, q7, #10 406 vadd.i32 q2, q2, q13 // += PREP_BIAS*64 407 vadd.i32 q3, q3, q13 408 vadd.i32 q4, q4, q13 409 vadd.i32 q5, q5, q13 410 vmovl.u16 q12, d12 411 vmovl.u16 q13, d13 412 vmla.i32 q2, q8, q12 // (tmp2-tmp1)*(64-m) 413 vmovl.u16 q12, d14 414 vmla.i32 q3, q9, q13 415 vmovl.u16 q13, d15 416 vmla.i32 q4, q10, q12 417 vmla.i32 q5, q11, q13 418 vrshl.s32 q2, q2, q14 // (tmp1<<6 + (tmp2-tmp1)*(64-m) + (1 << (sh-1)) + PREP_BIAS*64) >> sh 419 vrshl.s32 q3, q3, q14 420 vrshl.s32 q4, q4, q14 421 vrshl.s32 q5, q5, q14 422 vqmovun.s32 d4, q2 // iclip_pixel 423 vqmovun.s32 d5, q3 424 vqmovun.s32 d6, q4 425 vqmovun.s32 d7, q5 426 vmin.u16 q2, q2, q15 // iclip_pixel 427 vmin.u16 q3, q3, q15 // iclip_pixel 428.if \type == 444 429 vmovn.i16 d12, q6 // 64 - m 430 vmovn.i16 d13, q7 431 vsub.i16 q6, q1, q6 // m 432 vst1.8 {q6}, [r6, :128]! 433.elseif \type == 422 434 vpadd.i16 d12, d12, d13 // (64 - m) + (64 - n) (column wise addition) 435 vpadd.i16 d13, d14, d15 436 vmovn.i16 d12, q6 437 vhsub.u8 d12, d2, d12 // ((129 - sign) - ((64 - m) + (64 - n)) >> 1 438 vst1.8 {d12}, [r6, :64]! 439.elseif \type == 420 440 vadd.i16 q6, q6, q7 // (64 - my1) + (64 - my2) (row wise addition) 441 vpadd.i16 d12, d12, d13 // (128 - m) + (128 - n) (column wise addition) 442 vsub.i16 d12, d2, d12 // (256 - sign) - ((128 - m) + (128 - n)) 443 vrshrn.i16 d12, q6, #2 // ((256 - sign) - ((128 - m) + (128 - n)) + 2) >> 2 444 vst1.32 {d12[0]}, [r6, :32]! 445.endif 446 vst1.16 {q2}, [r0, :128], r1 447 vst1.16 {q3}, [r12, :128], r1 448 bgt 8b 449 vpop {q4-q7} 450 pop {r4-r10,pc} 4511280: 452640: 453320: 454160: 455 sub r1, r1, r4, lsl #1 456.if \type == 444 457 add lr, r6, r4 458.elseif \type == 422 459 add lr, r6, r4, lsr #1 460.endif 461 add r7, r2, r4, lsl #1 462 add r9, r3, r4, lsl #1 463161: 464 mov r8, r4 46516: 466 vld1.16 {q2}, [r2, :128]! // tmp1 467 vld1.16 {q4}, [r3, :128]! // tmp2 468 vld1.16 {q3}, [r7, :128]! 469 vld1.16 {q5}, [r9, :128]! 470 subs r8, r8, #8 471 vdup.32 q13, r10 // PREP_BIAS*64 472 vabd.s16 q6, q2, q4 // abs(tmp1 - tmp2) 473 vabd.s16 q7, q3, q5 474 vsubl.s16 q8, d8, d4 // tmp2 - tmp1 (requires 17 bit) 475 vsubl.s16 q9, d9, d5 476 vsubl.s16 q10, d10, d6 477 vsubl.s16 q11, d11, d7 478 vqsub.u16 q6, q0, q6 // 27615 - abs() 479 vqsub.u16 q7, q0, q7 480 vshll.s16 q5, d7, #6 // tmp1 << 6 481 vshll.s16 q4, d6, #6 482 vshll.s16 q3, d5, #6 483 vshll.s16 q2, d4, #6 484 vshr.u16 q6, q6, #10 // 64-m = (27615 - abs()) >> mask_sh 485 vshr.u16 q7, q7, #10 486 vadd.i32 q2, q2, q13 // += PREP_BIAS*64 487 vadd.i32 q3, q3, q13 488 vadd.i32 q4, q4, q13 489 vadd.i32 q5, q5, q13 490 vmovl.u16 q12, d12 491 vmovl.u16 q13, d13 492 vmla.i32 q2, q8, q12 // (tmp2-tmp1)*(64-m) 493 vmovl.u16 q12, d14 494 vmla.i32 q3, q9, q13 495 vmovl.u16 q13, d15 496 vmla.i32 q4, q10, q12 497 vmla.i32 q5, q11, q13 498 vrshl.s32 q2, q2, q14 // (tmp1<<6 + (tmp2-tmp1)*(64-m) + (1 << (sh-1)) + PREP_BIAS*64) >> sh 499 vrshl.s32 q3, q3, q14 500 vrshl.s32 q4, q4, q14 501 vrshl.s32 q5, q5, q14 502 vqmovun.s32 d4, q2 // iclip_pixel 503 vqmovun.s32 d5, q3 504 vqmovun.s32 d6, q4 505 vqmovun.s32 d7, q5 506 vmin.u16 q2, q2, q15 // iclip_pixel 507 vmin.u16 q3, q3, q15 // iclip_pixel 508.if \type == 444 509 vmovn.i16 d12, q6 // 64 - m 510 vmovn.i16 d13, q7 511 vsub.i16 q6, q1, q6 // m 512 vst1.8 {d12}, [r6, :64]! 513 vst1.8 {d13}, [lr, :64]! 514.elseif \type == 422 515 vpadd.i16 d12, d12, d13 // (64 - m) + (64 - n) (column wise addition) 516 vpadd.i16 d13, d14, d15 517 vmovn.i16 d12, q6 518 vhsub.u8 d12, d2, d12 // ((129 - sign) - ((64 - m) + (64 - n)) >> 1 519 vst1.32 {d12[0]}, [r6, :32]! 520 vst1.32 {d12[1]}, [lr, :32]! 521.elseif \type == 420 522 vadd.i16 q6, q6, q7 // (64 - my1) + (64 - my2) (row wise addition) 523 vpadd.i16 d12, d12, d13 // (128 - m) + (128 - n) (column wise addition) 524 vsub.i16 d12, d2, d12 // (256 - sign) - ((128 - m) + (128 - n)) 525 vrshrn.i16 d12, q6, #2 // ((256 - sign) - ((128 - m) + (128 - n)) + 2) >> 2 526 vst1.32 {d12[0]}, [r6, :32]! 527.endif 528 vst1.16 {q2}, [r0, :128]! 529 vst1.16 {q3}, [r12, :128]! 530 bgt 16b 531 subs r5, r5, #2 532 add r2, r2, r4, lsl #1 533 add r3, r3, r4, lsl #1 534 add r7, r7, r4, lsl #1 535 add r9, r9, r4, lsl #1 536.if \type == 444 537 add r6, r6, r4 538 add lr, lr, r4 539.elseif \type == 422 540 add r6, r6, r4, lsr #1 541 add lr, lr, r4, lsr #1 542.endif 543 add r0, r0, r1 544 add r12, r12, r1 545 bgt 161b 546 vpop {q4-q7} 547 pop {r4-r10,pc} 548endfunc 549.endm 550 551w_mask_fn 444 552w_mask_fn 422 553w_mask_fn 420 554 555function blend_16bpc_neon, export=1 556 push {r4-r5,lr} 557 ldrd r4, r5, [sp, #12] 558 clz lr, r3 559 adr r3, L(blend_tbl) 560 sub lr, lr, #26 561 ldr lr, [r3, lr, lsl #2] 562 add r3, r3, lr 563 bx r3 564 565 .align 2 566L(blend_tbl): 567 .word 320f - L(blend_tbl) + CONFIG_THUMB 568 .word 160f - L(blend_tbl) + CONFIG_THUMB 569 .word 80f - L(blend_tbl) + CONFIG_THUMB 570 .word 40f - L(blend_tbl) + CONFIG_THUMB 571 57240: 573 add r12, r0, r1 574 lsl r1, r1, #1 5754: 576 vld1.8 {d4}, [r5, :64]! 577 vld1.16 {q1}, [r2, :128]! 578 vld1.16 {d0}, [r0, :64] 579 vneg.s8 d4, d4 // -m 580 subs r4, r4, #2 581 vld1.16 {d1}, [r12, :64] 582 vmovl.s8 q2, d4 583 vshl.i16 q2, q2, #9 // -m << 9 584 vsub.i16 q1, q0, q1 // a - b 585 vqrdmulh.s16 q1, q1, q2 // ((a-b)*-m + 32) >> 6 586 vadd.i16 q0, q0, q1 587 vst1.16 {d0}, [r0, :64], r1 588 vst1.16 {d1}, [r12, :64], r1 589 bgt 4b 590 pop {r4-r5,pc} 59180: 592 add r12, r0, r1 593 lsl r1, r1, #1 5948: 595 vld1.8 {q8}, [r5, :128]! 596 vld1.16 {q2, q3}, [r2, :128]! 597 vneg.s8 q9, q8 // -m 598 vld1.16 {q0}, [r0, :128] 599 vld1.16 {q1}, [r12, :128] 600 vmovl.s8 q8, d18 601 vmovl.s8 q9, d19 602 vshl.i16 q8, q8, #9 // -m << 9 603 vshl.i16 q9, q9, #9 604 vsub.i16 q2, q0, q2 // a - b 605 vsub.i16 q3, q1, q3 606 subs r4, r4, #2 607 vqrdmulh.s16 q2, q2, q8 // ((a-b)*-m + 32) >> 6 608 vqrdmulh.s16 q3, q3, q9 609 vadd.i16 q0, q0, q2 610 vadd.i16 q1, q1, q3 611 vst1.16 {q0}, [r0, :128], r1 612 vst1.16 {q1}, [r12, :128], r1 613 bgt 8b 614 pop {r4-r5,pc} 615160: 616 add r12, r0, r1 617 lsl r1, r1, #1 61816: 619 vld1.8 {q12, q13}, [r5, :128]! 620 vld1.16 {q8, q9}, [r2, :128]! 621 subs r4, r4, #2 622 vneg.s8 q14, q12 // -m 623 vld1.16 {q0, q1}, [r0, :128] 624 vneg.s8 q15, q13 625 vld1.16 {q10, q11}, [r2, :128]! 626 vmovl.s8 q12, d28 627 vmovl.s8 q13, d29 628 vmovl.s8 q14, d30 629 vmovl.s8 q15, d31 630 vld1.16 {q2, q3}, [r12, :128] 631 vshl.i16 q12, q12, #9 // -m << 9 632 vshl.i16 q13, q13, #9 633 vshl.i16 q14, q14, #9 634 vshl.i16 q15, q15, #9 635 vsub.i16 q8, q0, q8 // a - b 636 vsub.i16 q9, q1, q9 637 vsub.i16 q10, q2, q10 638 vsub.i16 q11, q3, q11 639 vqrdmulh.s16 q8, q8, q12 // ((a-b)*-m + 32) >> 6 640 vqrdmulh.s16 q9, q9, q13 641 vqrdmulh.s16 q10, q10, q14 642 vqrdmulh.s16 q11, q11, q15 643 vadd.i16 q0, q0, q8 644 vadd.i16 q1, q1, q9 645 vadd.i16 q2, q2, q10 646 vst1.16 {q0, q1}, [r0, :128], r1 647 vadd.i16 q3, q3, q11 648 vst1.16 {q2, q3}, [r12, :128], r1 649 bgt 16b 650 pop {r4-r5,pc} 651320: 652 add r12, r0, #32 65332: 654 vld1.8 {q12, q13}, [r5, :128]! 655 vld1.16 {q8, q9}, [r2, :128]! 656 subs r4, r4, #1 657 vneg.s8 q14, q12 // -m 658 vld1.16 {q0, q1}, [r0, :128] 659 vneg.s8 q15, q13 660 vld1.16 {q10, q11}, [r2, :128]! 661 vmovl.s8 q12, d28 662 vmovl.s8 q13, d29 663 vmovl.s8 q14, d30 664 vmovl.s8 q15, d31 665 vld1.16 {q2, q3}, [r12, :128] 666 vshl.i16 q12, q12, #9 // -m << 9 667 vshl.i16 q13, q13, #9 668 vshl.i16 q14, q14, #9 669 vshl.i16 q15, q15, #9 670 vsub.i16 q8, q0, q8 // a - b 671 vsub.i16 q9, q1, q9 672 vsub.i16 q10, q2, q10 673 vsub.i16 q11, q3, q11 674 vqrdmulh.s16 q8, q8, q12 // ((a-b)*-m + 32) >> 6 675 vqrdmulh.s16 q9, q9, q13 676 vqrdmulh.s16 q10, q10, q14 677 vqrdmulh.s16 q11, q11, q15 678 vadd.i16 q0, q0, q8 679 vadd.i16 q1, q1, q9 680 vadd.i16 q2, q2, q10 681 vst1.16 {q0, q1}, [r0, :128], r1 682 vadd.i16 q3, q3, q11 683 vst1.16 {q2, q3}, [r12, :128], r1 684 bgt 32b 685 pop {r4-r5,pc} 686endfunc 687 688function blend_h_16bpc_neon, export=1 689 push {r4-r5,lr} 690 ldr r4, [sp, #12] 691 movrel r5, X(obmc_masks) 692 add r5, r5, r4 693 sub r4, r4, r4, lsr #2 694 clz lr, r3 695 adr r12, L(blend_h_tbl) 696 sub lr, lr, #24 697 ldr lr, [r12, lr, lsl #2] 698 add r12, r12, lr 699 bx r12 700 701 .align 2 702L(blend_h_tbl): 703 .word 1280f - L(blend_h_tbl) + CONFIG_THUMB 704 .word 640f - L(blend_h_tbl) + CONFIG_THUMB 705 .word 320f - L(blend_h_tbl) + CONFIG_THUMB 706 .word 160f - L(blend_h_tbl) + CONFIG_THUMB 707 .word 80f - L(blend_h_tbl) + CONFIG_THUMB 708 .word 40f - L(blend_h_tbl) + CONFIG_THUMB 709 .word 20f - L(blend_h_tbl) + CONFIG_THUMB 710 71120: 712 add r12, r0, r1 713 lsl r1, r1, #1 7142: 715 vld2.8 {d4[], d5[]}, [r5, :16]! 716 vld1.16 {d2}, [r2, :64]! 717 vext.8 d4, d4, d5, #6 718 subs r4, r4, #2 719 vneg.s8 d4, d4 // -m 720 vld1.32 {d0[]}, [r0, :32] 721 vld1.32 {d0[1]}, [r12, :32] 722 vmovl.s8 q2, d4 723 vshl.i16 d4, d4, #9 // -m << 9 724 vsub.i16 d2, d0, d2 // a - b 725 vqrdmulh.s16 d2, d2, d4 // ((a-b)*-m + 32) >> 6 726 vadd.i16 d0, d0, d2 727 vst1.32 {d0[0]}, [r0, :32], r1 728 vst1.32 {d0[1]}, [r12, :32], r1 729 bgt 2b 730 pop {r4-r5,pc} 73140: 732 add r12, r0, r1 733 lsl r1, r1, #1 7344: 735 vld2.8 {d4[], d5[]}, [r5, :16]! 736 vld1.16 {q1}, [r2, :128]! 737 vext.8 d4, d4, d5, #4 738 subs r4, r4, #2 739 vneg.s8 d4, d4 // -m 740 vld1.16 {d0}, [r0, :64] 741 vld1.16 {d1}, [r12, :64] 742 vmovl.s8 q2, d4 743 vshl.i16 q2, q2, #9 // -m << 9 744 vsub.i16 q1, q0, q1 // a - b 745 vqrdmulh.s16 q1, q1, q2 // ((a-b)*-m + 32) >> 6 746 vadd.i16 q0, q0, q1 747 vst1.16 {d0}, [r0, :64], r1 748 vst1.16 {d1}, [r12, :64], r1 749 bgt 4b 750 pop {r4-r5,pc} 75180: 752 add r12, r0, r1 753 lsl r1, r1, #1 7548: 755 vld2.8 {d16[], d17[]}, [r5, :16]! 756 vld1.16 {q2, q3}, [r2, :128]! 757 vneg.s8 q9, q8 // -m 758 vld1.16 {q0}, [r0, :128] 759 subs r4, r4, #2 760 vmovl.s8 q8, d18 761 vmovl.s8 q9, d19 762 vld1.16 {q1}, [r12, :128] 763 vshl.i16 q8, q8, #9 // -m << 9 764 vshl.i16 q9, q9, #9 765 vsub.i16 q2, q0, q2 // a - b 766 vsub.i16 q3, q1, q3 767 vqrdmulh.s16 q2, q2, q8 // ((a-b)*-m + 32) >> 6 768 vqrdmulh.s16 q3, q3, q9 769 vadd.i16 q0, q0, q2 770 vadd.i16 q1, q1, q3 771 vst1.16 {q0}, [r0, :128], r1 772 vst1.16 {q1}, [r12, :128], r1 773 bgt 8b 774 pop {r4-r5,pc} 775160: 776 add r12, r0, r1 777 lsl r1, r1, #1 77816: 779 vld2.8 {d24[], d25[]}, [r5, :16]! 780 vld1.16 {q8, q9}, [r2, :128]! 781 subs r4, r4, #2 782 vneg.s8 q13, q12 // -m 783 vld1.16 {q0, q1}, [r0, :128] 784 vmovl.s8 q12, d26 785 vld1.16 {q10, q11}, [r2, :128]! 786 vmovl.s8 q13, d27 787 vld1.16 {q2, q3}, [r12, :128] 788 vshl.i16 q12, q12, #9 // -m << 9 789 vshl.i16 q13, q13, #9 790 vsub.i16 q8, q0, q8 // a - b 791 vsub.i16 q9, q1, q9 792 vsub.i16 q10, q2, q10 793 vsub.i16 q11, q3, q11 794 vqrdmulh.s16 q8, q8, q12 // ((a-b)*-m + 32) >> 6 795 vqrdmulh.s16 q9, q9, q12 796 vqrdmulh.s16 q10, q10, q13 797 vqrdmulh.s16 q11, q11, q13 798 vadd.i16 q0, q0, q8 799 vadd.i16 q1, q1, q9 800 vadd.i16 q2, q2, q10 801 vadd.i16 q3, q3, q11 802 vst1.16 {q0, q1}, [r0, :128], r1 803 vst1.16 {q2, q3}, [r12, :128], r1 804 bgt 16b 805 pop {r4-r5,pc} 8061280: 807640: 808320: 809 sub r1, r1, r3, lsl #1 810321: 811 vld1.8 {d24[]}, [r5]! 812 mov r12, r3 813 vneg.s8 d24, d24 // -m 814 vmovl.s8 q12, d24 815 vshl.i16 q12, q12, #9 // -m << 9 81632: 817 vld1.16 {q8, q9}, [r2, :128]! 818 vld1.16 {q0, q1}, [r0, :128]! 819 subs r12, r12, #32 820 vld1.16 {q10, q11}, [r2, :128]! 821 vld1.16 {q2, q3}, [r0, :128] 822 vsub.i16 q8, q0, q8 // a - b 823 vsub.i16 q9, q1, q9 824 vsub.i16 q10, q2, q10 825 vsub.i16 q11, q3, q11 826 sub r0, r0, #32 827 vqrdmulh.s16 q8, q8, q12 // ((a-b)*-m + 32) >> 6 828 vqrdmulh.s16 q9, q9, q12 829 vqrdmulh.s16 q10, q10, q12 830 vqrdmulh.s16 q11, q11, q12 831 vadd.i16 q0, q0, q8 832 vadd.i16 q1, q1, q9 833 vadd.i16 q2, q2, q10 834 vst1.16 {q0, q1}, [r0, :128]! 835 vadd.i16 q3, q3, q11 836 vst1.16 {q2, q3}, [r0, :128]! 837 bgt 32b 838 subs r4, r4, #1 839 add r0, r0, r1 840 bgt 321b 841 pop {r4-r5,pc} 842endfunc 843 844function blend_v_16bpc_neon, export=1 845 push {r4,lr} 846 ldr r4, [sp, #8] 847 movrel lr, X(obmc_masks) 848 add lr, lr, r3 849 clz r12, r3 850 adr r3, L(blend_v_tbl) 851 sub r12, r12, #26 852 ldr r12, [r3, r12, lsl #2] 853 add r3, r3, r12 854 bx r3 855 856 .align 2 857L(blend_v_tbl): 858 .word 320f - L(blend_v_tbl) + CONFIG_THUMB 859 .word 160f - L(blend_v_tbl) + CONFIG_THUMB 860 .word 80f - L(blend_v_tbl) + CONFIG_THUMB 861 .word 40f - L(blend_v_tbl) + CONFIG_THUMB 862 .word 20f - L(blend_v_tbl) + CONFIG_THUMB 863 86420: 865 add r12, r0, r1 866 lsl r1, r1, #1 867 vld1.8 {d4[]}, [lr] 868 vneg.s8 d4, d4 // -m 869 vmovl.s8 q2, d4 870 vshl.i16 d4, d4, #9 // -m << 9 8712: 872 vld1.32 {d2[]}, [r2, :32]! 873 vld1.16 {d0[]}, [r0, :16] 874 subs r4, r4, #2 875 vld1.16 {d2[1]}, [r2, :16] 876 vld1.16 {d0[1]}, [r12, :16] 877 add r2, r2, #4 878 vsub.i16 d2, d0, d2 // a - b 879 vqrdmulh.s16 d2, d2, d4 // ((a-b)*-m + 32) >> 6 880 vadd.i16 d0, d0, d2 881 vst1.16 {d0[0]}, [r0, :16], r1 882 vst1.16 {d0[1]}, [r12, :16], r1 883 bgt 2b 884 pop {r4,pc} 88540: 886 vld1.32 {d4[]}, [lr, :32] 887 add r12, r0, r1 888 vneg.s8 d4, d4 // -m 889 lsl r1, r1, #1 890 vmovl.s8 q2, d4 891 sub r1, r1, #4 892 vshl.i16 q2, q2, #9 // -m << 9 8934: 894 vld1.16 {q1}, [r2, :128]! 895 vld1.16 {d0}, [r0, :64] 896 vld1.16 {d1}, [r12, :64] 897 subs r4, r4, #2 898 vsub.i16 q1, q0, q1 // a - b 899 vqrdmulh.s16 q1, q1, q2 // ((a-b)*-m + 32) >> 6 900 vadd.i16 q0, q0, q1 901 vst1.32 {d0[0]}, [r0, :32]! 902 vst1.32 {d1[0]}, [r12, :32]! 903 vst1.16 {d0[2]}, [r0, :16], r1 904 vst1.16 {d1[2]}, [r12, :16], r1 905 bgt 4b 906 pop {r4,pc} 90780: 908 vld1.8 {d16}, [lr, :64] 909 add r12, r0, r1 910 vneg.s8 d16, d16 // -m 911 lsl r1, r1, #1 912 vmovl.s8 q8, d16 913 sub r1, r1, #8 914 vshl.i16 q8, q8, #9 // -m << 9 9158: 916 vld1.16 {q2, q3}, [r2, :128]! 917 vld1.16 {q0}, [r0, :128] 918 vld1.16 {q1}, [r12, :128] 919 subs r4, r4, #2 920 vsub.i16 q2, q0, q2 // a - b 921 vsub.i16 q3, q1, q3 922 vqrdmulh.s16 q2, q2, q8 // ((a-b)*-m + 32) >> 6 923 vqrdmulh.s16 q3, q3, q8 924 vadd.i16 q0, q0, q2 925 vadd.i16 q1, q1, q3 926 vst1.16 {d0}, [r0, :64]! 927 vst1.16 {d2}, [r12, :64]! 928 vst1.32 {d1[0]}, [r0, :32], r1 929 vst1.32 {d3[0]}, [r12, :32], r1 930 bgt 8b 931 pop {r4,pc} 932160: 933 vld1.8 {q12}, [lr, :128] 934 add r12, r0, r1 935 vneg.s8 q13, q12 // -m 936 lsl r1, r1, #1 937 vmovl.s8 q12, d26 938 vmovl.s8 q13, d27 939 vshl.i16 q12, q12, #9 // -m << 9 940 vshl.i16 d26, d26, #9 94116: 942 vld1.16 {q8, q9}, [r2, :128]! 943 vld1.16 {d0, d1, d2}, [r0, :64] 944 subs r4, r4, #2 945 vld1.16 {q10, q11}, [r2, :128]! 946 vsub.i16 q8, q0, q8 // a - b 947 vld1.16 {d4, d5, d6}, [r12, :64] 948 vsub.i16 d18, d2, d18 949 vsub.i16 q10, q2, q10 950 vsub.i16 d22, d6, d22 951 vqrdmulh.s16 q8, q8, q12 // ((a-b)*-m + 32) >> 6 952 vqrdmulh.s16 d18, d18, d26 953 vqrdmulh.s16 q10, q10, q12 954 vqrdmulh.s16 d22, d22, d26 955 vadd.i16 q0, q0, q8 956 vadd.i16 d2, d2, d18 957 vadd.i16 q2, q2, q10 958 vst1.16 {d0, d1, d2}, [r0, :64], r1 959 vadd.i16 d6, d6, d22 960 vst1.16 {d4, d5, d6}, [r12, :64], r1 961 bgt 16b 962 pop {r4,pc} 963320: 964 vld1.8 {d24, d25, d26}, [lr, :64] 965 vneg.s8 q14, q12 // -m 966 vneg.s8 d30, d26 967 vmovl.s8 q12, d28 968 vmovl.s8 q13, d29 969 vmovl.s8 q14, d30 970 sub r1, r1, #32 971 vshl.i16 q12, q12, #9 // -m << 9 972 vshl.i16 q13, q13, #9 973 vshl.i16 q14, q14, #9 97432: 975 vld1.16 {q8, q9}, [r2, :128]! 976 vld1.16 {q0, q1}, [r0, :128]! 977 subs r4, r4, #1 978 vld1.16 {q10}, [r2, :128] 979 vsub.i16 q8, q0, q8 // a - b 980 vld1.16 {q2}, [r0, :128] 981 sub r0, r0, #32 982 vsub.i16 q9, q1, q9 983 vsub.i16 q10, q2, q10 984 vqrdmulh.s16 q8, q8, q12 // ((a-b)*-m + 32) >> 6 985 vqrdmulh.s16 q9, q9, q13 986 vqrdmulh.s16 q10, q10, q14 987 vadd.i16 q0, q0, q8 988 vadd.i16 q1, q1, q9 989 vadd.i16 q2, q2, q10 990 vst1.16 {q0, q1}, [r0, :128]! 991 add r2, r2, #32 992 vst1.16 {q2}, [r0, :128], r1 993 bgt 32b 994 pop {r4,pc} 995endfunc 996 997// This has got the same signature as the put_8tap functions, 998// and assumes that r9 is set to (clz(w)-24). 999function put_neon 1000 adr r10, L(put_tbl) 1001 ldr r9, [r10, r9, lsl #2] 1002 add r10, r10, r9 1003 bx r10 1004 1005 .align 2 1006L(put_tbl): 1007 .word 1280f - L(put_tbl) + CONFIG_THUMB 1008 .word 640f - L(put_tbl) + CONFIG_THUMB 1009 .word 320f - L(put_tbl) + CONFIG_THUMB 1010 .word 16f - L(put_tbl) + CONFIG_THUMB 1011 .word 80f - L(put_tbl) + CONFIG_THUMB 1012 .word 4f - L(put_tbl) + CONFIG_THUMB 1013 .word 2f - L(put_tbl) + CONFIG_THUMB 1014 10152: 1016 vld1.32 {d0[]}, [r2], r3 1017 vld1.32 {d1[]}, [r2], r3 1018 subs r5, r5, #2 1019 vst1.32 {d0[0]}, [r0, :32], r1 1020 vst1.32 {d1[1]}, [r0, :32], r1 1021 bgt 2b 1022 pop {r4-r11,pc} 10234: 1024 vld1.16 {d0}, [r2], r3 1025 vld1.16 {d1}, [r2], r3 1026 subs r5, r5, #2 1027 vst1.16 {d0}, [r0, :64], r1 1028 vst1.16 {d1}, [r0, :64], r1 1029 bgt 4b 1030 pop {r4-r11,pc} 103180: 1032 add r8, r0, r1 1033 lsl r1, r1, #1 1034 add r9, r2, r3 1035 lsl r3, r3, #1 10368: 1037 vld1.16 {q0}, [r2], r3 1038 vld1.16 {q1}, [r9], r3 1039 subs r5, r5, #2 1040 vst1.16 {q0}, [r0, :128], r1 1041 vst1.16 {q1}, [r8, :128], r1 1042 bgt 8b 1043 pop {r4-r11,pc} 104416: 1045 vld1.16 {q0, q1}, [r2], r3 1046 subs r5, r5, #1 1047 vst1.16 {q0, q1}, [r0, :128], r1 1048 bgt 16b 1049 pop {r4-r11,pc} 1050320: 1051 sub r1, r1, #32 1052 sub r3, r3, #32 105332: 1054 vld1.16 {q0, q1}, [r2]! 1055 vst1.16 {q0, q1}, [r0, :128]! 1056 vld1.16 {q2, q3}, [r2], r3 1057 subs r5, r5, #1 1058 vst1.16 {q2, q3}, [r0, :128], r1 1059 bgt 32b 1060 pop {r4-r11,pc} 1061640: 1062 sub r1, r1, #96 1063 sub r3, r3, #96 106464: 1065 vld1.16 {q8, q9}, [r2]! 1066 vst1.16 {q8, q9}, [r0, :128]! 1067 vld1.16 {q10, q11}, [r2]! 1068 vst1.16 {q10, q11}, [r0, :128]! 1069 vld1.16 {q12, q13}, [r2]! 1070 vst1.16 {q12, q13}, [r0, :128]! 1071 vld1.16 {q14, q15}, [r2], r3 1072 subs r5, r5, #1 1073 vst1.16 {q14, q15}, [r0, :128], r1 1074 bgt 64b 1075 pop {r4-r11,pc} 10761280: 1077 sub r1, r1, #224 1078 sub r3, r3, #224 1079128: 1080 vld1.16 {q8, q9}, [r2]! 1081 vst1.16 {q8, q9}, [r0, :128]! 1082 vld1.16 {q10, q11}, [r2]! 1083 vst1.16 {q10, q11}, [r0, :128]! 1084 vld1.16 {q12, q13}, [r2]! 1085 vst1.16 {q12, q13}, [r0, :128]! 1086 vld1.16 {q14, q15}, [r2]! 1087 vst1.16 {q14, q15}, [r0, :128]! 1088 vld1.16 {q8, q9}, [r2]! 1089 vst1.16 {q8, q9}, [r0, :128]! 1090 vld1.16 {q10, q11}, [r2]! 1091 vst1.16 {q10, q11}, [r0, :128]! 1092 vld1.16 {q12, q13}, [r2]! 1093 vst1.16 {q12, q13}, [r0, :128]! 1094 vld1.16 {q14, q15}, [r2], r3 1095 subs r5, r5, #1 1096 vst1.16 {q14, q15}, [r0, :128], r1 1097 bgt 128b 1098 pop {r4-r11,pc} 1099endfunc 1100 1101// This has got the same signature as the prep_8tap functions, 1102// and assumes that r9 is set to (clz(w)-24), r7 to intermediate_bits and 1103// r8 to w*2. 1104function prep_neon 1105 adr r10, L(prep_tbl) 1106 ldr r9, [r10, r9, lsl #2] 1107 vdup.16 q15, r7 // intermediate_bits 1108 vmov.i16 q14, #PREP_BIAS 1109 add r10, r10, r9 1110 bx r10 1111 1112 .align 2 1113L(prep_tbl): 1114 .word 1280f - L(prep_tbl) + CONFIG_THUMB 1115 .word 640f - L(prep_tbl) + CONFIG_THUMB 1116 .word 320f - L(prep_tbl) + CONFIG_THUMB 1117 .word 16f - L(prep_tbl) + CONFIG_THUMB 1118 .word 80f - L(prep_tbl) + CONFIG_THUMB 1119 .word 40f - L(prep_tbl) + CONFIG_THUMB 1120 112140: 1122 add r9, r1, r2 1123 lsl r2, r2, #1 11244: 1125 vld1.16 {d0}, [r1], r2 1126 vld1.16 {d1}, [r9], r2 1127 subs r4, r4, #2 1128 vshl.s16 q0, q0, q15 1129 vsub.i16 q0, q0, q14 1130 vst1.16 {q0}, [r0, :128]! 1131 bgt 4b 1132 pop {r4-r11,pc} 113380: 1134 add r9, r1, r2 1135 lsl r2, r2, #1 11368: 1137 vld1.16 {q0}, [r1], r2 1138 vld1.16 {q1}, [r9], r2 1139 subs r4, r4, #2 1140 vshl.s16 q0, q0, q15 1141 vshl.s16 q1, q1, q15 1142 vsub.i16 q0, q0, q14 1143 vsub.i16 q1, q1, q14 1144 vst1.16 {q0, q1}, [r0, :128]! 1145 bgt 8b 1146 pop {r4-r11,pc} 114716: 1148 vld1.16 {q0, q1}, [r1], r2 1149 vshl.s16 q0, q0, q15 1150 vld1.16 {q2, q3}, [r1], r2 1151 subs r4, r4, #2 1152 vshl.s16 q1, q1, q15 1153 vshl.s16 q2, q2, q15 1154 vshl.s16 q3, q3, q15 1155 vsub.i16 q0, q0, q14 1156 vsub.i16 q1, q1, q14 1157 vsub.i16 q2, q2, q14 1158 vst1.16 {q0, q1}, [r0, :128]! 1159 vsub.i16 q3, q3, q14 1160 vst1.16 {q2, q3}, [r0, :128]! 1161 bgt 16b 1162 pop {r4-r11,pc} 1163320: 1164 sub r2, r2, #32 116532: 1166 vld1.16 {q0, q1}, [r1]! 1167 subs r4, r4, #1 1168 vshl.s16 q0, q0, q15 1169 vld1.16 {q2, q3}, [r1], r2 1170 vshl.s16 q1, q1, q15 1171 vshl.s16 q2, q2, q15 1172 vshl.s16 q3, q3, q15 1173 vsub.i16 q0, q0, q14 1174 vsub.i16 q1, q1, q14 1175 vsub.i16 q2, q2, q14 1176 vst1.16 {q0, q1}, [r0, :128]! 1177 vsub.i16 q3, q3, q14 1178 vst1.16 {q2, q3}, [r0, :128]! 1179 bgt 32b 1180 pop {r4-r11,pc} 1181640: 1182 sub r2, r2, #96 118364: 1184 vld1.16 {q0, q1}, [r1]! 1185 subs r4, r4, #1 1186 vshl.s16 q0, q0, q15 1187 vld1.16 {q2, q3}, [r1]! 1188 vshl.s16 q1, q1, q15 1189 vld1.16 {q8, q9}, [r1]! 1190 vshl.s16 q2, q2, q15 1191 vld1.16 {q10, q11}, [r1], r2 1192 vshl.s16 q3, q3, q15 1193 vshl.s16 q8, q8, q15 1194 vshl.s16 q9, q9, q15 1195 vshl.s16 q10, q10, q15 1196 vshl.s16 q11, q11, q15 1197 vsub.i16 q0, q0, q14 1198 vsub.i16 q1, q1, q14 1199 vsub.i16 q2, q2, q14 1200 vsub.i16 q3, q3, q14 1201 vsub.i16 q8, q8, q14 1202 vst1.16 {q0, q1}, [r0, :128]! 1203 vsub.i16 q9, q9, q14 1204 vst1.16 {q2, q3}, [r0, :128]! 1205 vsub.i16 q10, q10, q14 1206 vst1.16 {q8, q9}, [r0, :128]! 1207 vsub.i16 q11, q11, q14 1208 vst1.16 {q10, q11}, [r0, :128]! 1209 bgt 64b 1210 pop {r4-r11,pc} 12111280: 1212 sub r2, r2, #224 1213128: 1214 vld1.16 {q0, q1}, [r1]! 1215 subs r4, r4, #1 1216 vshl.s16 q0, q0, q15 1217 vld1.16 {q2, q3}, [r1]! 1218 vshl.s16 q1, q1, q15 1219 vld1.16 {q8, q9}, [r1]! 1220 vshl.s16 q2, q2, q15 1221 vld1.16 {q10, q11}, [r1]! 1222 vshl.s16 q3, q3, q15 1223 vshl.s16 q8, q8, q15 1224 vshl.s16 q9, q9, q15 1225 vshl.s16 q10, q10, q15 1226 vshl.s16 q11, q11, q15 1227 vsub.i16 q0, q0, q14 1228 vsub.i16 q1, q1, q14 1229 vsub.i16 q2, q2, q14 1230 vsub.i16 q3, q3, q14 1231 vsub.i16 q8, q8, q14 1232 vst1.16 {q0, q1}, [r0, :128]! 1233 vld1.16 {q0, q1}, [r1]! 1234 vsub.i16 q9, q9, q14 1235 vsub.i16 q10, q10, q14 1236 vst1.16 {q2, q3}, [r0, :128]! 1237 vld1.16 {q2, q3}, [r1]! 1238 vsub.i16 q11, q11, q14 1239 vshl.s16 q0, q0, q15 1240 vst1.16 {q8, q9}, [r0, :128]! 1241 vld1.16 {q8, q9}, [r1]! 1242 vshl.s16 q1, q1, q15 1243 vshl.s16 q2, q2, q15 1244 vst1.16 {q10, q11}, [r0, :128]! 1245 vld1.16 {q10, q11}, [r1], r2 1246 vshl.s16 q3, q3, q15 1247 vshl.s16 q8, q8, q15 1248 vshl.s16 q9, q9, q15 1249 vshl.s16 q10, q10, q15 1250 vshl.s16 q11, q11, q15 1251 vsub.i16 q0, q0, q14 1252 vsub.i16 q1, q1, q14 1253 vsub.i16 q2, q2, q14 1254 vsub.i16 q3, q3, q14 1255 vsub.i16 q8, q8, q14 1256 vst1.16 {q0, q1}, [r0, :128]! 1257 vsub.i16 q9, q9, q14 1258 vst1.16 {q2, q3}, [r0, :128]! 1259 vsub.i16 q10, q10, q14 1260 vst1.16 {q8, q9}, [r0, :128]! 1261 vsub.i16 q11, q11, q14 1262 vst1.16 {q10, q11}, [r0, :128]! 1263 bgt 128b 1264 pop {r4-r11,pc} 1265endfunc 1266 1267.macro load_slice s0, s1, strd, wd, d0, d1, d2, d3, d4, d5, d6 1268 vld1.\wd {\d0[]}, [\s0], \strd 1269 vld1.\wd {\d1[]}, [\s1], \strd 1270.ifnb \d2 1271 vld1.\wd {\d2[]}, [\s0], \strd 1272 vld1.\wd {\d3[]}, [\s1], \strd 1273.endif 1274.ifnb \d4 1275 vld1.\wd {\d4[]}, [\s0], \strd 1276.endif 1277.ifnb \d5 1278 vld1.\wd {\d5[]}, [\s1], \strd 1279.endif 1280.ifnb \d6 1281 vld1.\wd {\d6[]}, [\s0], \strd 1282.endif 1283.endm 1284.macro load_reg s0, s1, strd, d0, d1, d2, d3, d4, d5, d6 1285 vld1.16 {\d0}, [\s0], \strd 1286 vld1.16 {\d1}, [\s1], \strd 1287.ifnb \d2 1288 vld1.16 {\d2}, [\s0], \strd 1289 vld1.16 {\d3}, [\s1], \strd 1290.endif 1291.ifnb \d4 1292 vld1.16 {\d4}, [\s0], \strd 1293.endif 1294.ifnb \d5 1295 vld1.16 {\d5}, [\s1], \strd 1296.endif 1297.ifnb \d6 1298 vld1.16 {\d6}, [\s0], \strd 1299.endif 1300.endm 1301.macro load_regpair s0, s1, strd, d0, d1, d2, d3, d4, d5 1302 vld1.16 {\d0, \d1}, [\s0], \strd 1303.ifnb \d2 1304 vld1.16 {\d2, \d3}, [\s1], \strd 1305.endif 1306.ifnb \d4 1307 vld1.16 {\d4, \d5}, [\s0], \strd 1308.endif 1309.endm 1310.macro load_32 s0, s1, strd, d0, d1, d2, d3, d4, d5, d6 1311 load_slice \s0, \s1, \strd, 32, \d0, \d1, \d2, \d3, \d4, \d5, \d6 1312.endm 1313.macro load_16s16 s0, s1, strd, d0, d1, d2, d3, d4, d5 1314 load_regpair \s0, \s1, \strd, \d0, \d1, \d2, \d3, \d4, \d5 1315.endm 1316.macro interleave_1_32 r0, r1, r2, r3, r4 1317 vext.8 \r0, \r0, \r1, #4 1318 vext.8 \r1, \r1, \r2, #4 1319.ifnb \r3 1320 vext.8 \r2, \r2, \r3, #4 1321 vext.8 \r3, \r3, \r4, #4 1322.endif 1323.endm 1324.macro vmin_u16 c, r0, r1, r2, r3 1325 vmin.u16 \r0, \r0, \c 1326.ifnb \r1 1327 vmin.u16 \r1, \r1, \c 1328.endif 1329.ifnb \r2 1330 vmin.u16 \r2, \r2, \c 1331 vmin.u16 \r3, \r3, \c 1332.endif 1333.endm 1334.macro vsub_i16 c, r0, r1, r2, r3 1335 vsub.i16 \r0, \r0, \c 1336.ifnb \r1 1337 vsub.i16 \r1, \r1, \c 1338.endif 1339.ifnb \r2 1340 vsub.i16 \r2, \r2, \c 1341 vsub.i16 \r3, \r3, \c 1342.endif 1343.endm 1344.macro vmull_vmlal_4 d, s0, s1, s2, s3 1345 vmull.s16 \d, \s0, d0[0] 1346 vmlal.s16 \d, \s1, d0[1] 1347 vmlal.s16 \d, \s2, d0[2] 1348 vmlal.s16 \d, \s3, d0[3] 1349.endm 1350.macro vmull_vmlal_8 d, s0, s1, s2, s3, s4, s5, s6, s7 1351 vmull.s16 \d, \s0, d0[0] 1352 vmlal.s16 \d, \s1, d0[1] 1353 vmlal.s16 \d, \s2, d0[2] 1354 vmlal.s16 \d, \s3, d0[3] 1355 vmlal.s16 \d, \s4, d1[0] 1356 vmlal.s16 \d, \s5, d1[1] 1357 vmlal.s16 \d, \s6, d1[2] 1358 vmlal.s16 \d, \s7, d1[3] 1359.endm 1360.macro vqrshrun_s32 shift, q0, d0, q1, d1, q2, d2, q3, d3 1361 vqrshrun.s32 \d0, \q0, #\shift 1362.ifnb \q1 1363 vqrshrun.s32 \d1, \q1, #\shift 1364.endif 1365.ifnb \q2 1366 vqrshrun.s32 \d2, \q2, #\shift 1367 vqrshrun.s32 \d3, \q3, #\shift 1368.endif 1369.endm 1370.macro vmovn_i32 q0, d0, q1, d1, q2, d2, q3, d3 1371 vmovn.i32 \d0, \q0 1372.ifnb \q1 1373 vmovn.i32 \d1, \q1 1374.endif 1375.ifnb \q2 1376 vmovn.i32 \d2, \q2 1377 vmovn.i32 \d3, \q3 1378.endif 1379.endm 1380.macro vrshl_s32 shift, r0, r1, r2, r3 1381 vrshl.s32 \r0, \r0, \shift 1382 vrshl.s32 \r1, \r1, \shift 1383.ifnb \r2 1384 vrshl.s32 \r2, \r2, \shift 1385 vrshl.s32 \r3, \r3, \shift 1386.endif 1387.endm 1388.macro vst1_32 strd, r0, r1 1389 vst1.32 {\r0[0]}, [r0, :32], \strd 1390 vst1.32 {\r0[1]}, [r9, :32], \strd 1391.ifnb \r1 1392 vst1.32 {\r1[0]}, [r0, :32], \strd 1393 vst1.32 {\r1[1]}, [r9, :32], \strd 1394.endif 1395.endm 1396.macro vst1_reg strd, align, r0, r1, r2, r3, r4, r5, r6, r7 1397 vst1.16 {\r0}, [r0, \align], \strd 1398 vst1.16 {\r1}, [r9, \align], \strd 1399.ifnb \r2 1400 vst1.16 {\r2}, [r0, \align], \strd 1401 vst1.16 {\r3}, [r9, \align], \strd 1402.endif 1403.ifnb \r4 1404 vst1.16 {\r4}, [r0, \align], \strd 1405 vst1.16 {\r5}, [r9, \align], \strd 1406 vst1.16 {\r6}, [r0, \align], \strd 1407 vst1.16 {\r7}, [r9, \align], \strd 1408.endif 1409.endm 1410.macro finalize type, q0, q1, d0, d1, q2, q3, d2, d3 1411.ifc \type, put 1412 vqrshrun_s32 6, \q0, \d0, \q1, \d1, \q2, \d2, \q3, \d3 1413 vmin_u16 q15, \q0, \q1 1414.else 1415 vrshl_s32 q14, \q0, \q1, \q2, \q3 // -(6-intermediate_bits) 1416 vmovn_i32 \q0, \d0, \q1, \d1, \q2, \d2, \q3, \d3 1417 vsub_i16 q15, \q0, \q1 // PREP_BIAS 1418.endif 1419.endm 1420.macro shift_store_4 type, strd, q0, q1, d0, d1, q2, q3, d2, d3 1421 finalize \type, \q0, \q1, \d0, \d1, \q2, \q3, \d2, \d3 1422 vst1_reg \strd, :64, \d0, \d1, \d2, \d3 1423.endm 1424.macro shift_store_8 type, strd, q0, q1, d0, d1, q2, q3, d2, d3 1425 finalize \type, \q0, \q1, \d0, \d1, \q2, \q3, \d2, \d3 1426 vst1_reg \strd, :128, \q0, \q1 1427.endm 1428.macro shift_store_16 type, strd, q0, q1, d0, d1, q2, q3, d2, d3 1429 finalize \type, \q0, \q1, \d0, \d1, \q2, \q3, \d2, \d3 1430 vst1.16 {\q0, \q1}, [r0, :128], \strd 1431.endm 1432 1433.macro make_8tap_fn op, type, type_h, type_v 1434function \op\()_8tap_\type\()_16bpc_neon, export=1 1435 push {r4-r11,lr} 1436 movw r9, \type_h 1437 movw r10, \type_v 1438 b \op\()_8tap_neon 1439endfunc 1440.endm 1441 1442// No spaces in these expressions, due to gas-preprocessor. 1443#define REGULAR ((0*15<<7)|3*15) 1444#define SMOOTH ((1*15<<7)|4*15) 1445#define SHARP ((2*15<<7)|3*15) 1446 1447.macro filter_fn type, dst, d_strd, src, s_strd, w, h, mx, my, bdmax, ds2, sr2 1448make_8tap_fn \type, regular, REGULAR, REGULAR 1449make_8tap_fn \type, regular_smooth, REGULAR, SMOOTH 1450make_8tap_fn \type, regular_sharp, REGULAR, SHARP 1451make_8tap_fn \type, smooth, SMOOTH, SMOOTH 1452make_8tap_fn \type, smooth_regular, SMOOTH, REGULAR 1453make_8tap_fn \type, smooth_sharp, SMOOTH, SHARP 1454make_8tap_fn \type, sharp, SHARP, SHARP 1455make_8tap_fn \type, sharp_regular, SHARP, REGULAR 1456make_8tap_fn \type, sharp_smooth, SHARP, SMOOTH 1457 1458function \type\()_8tap_neon 1459 ldrd r4, r5, [sp, #36] 1460 ldrd r6, r7, [sp, #44] 1461.ifc \bdmax, r8 1462 ldr r8, [sp, #52] 1463.endif 1464 movw r11, #0x4081 // (1 << 14) | (1 << 7) | (1 << 0) 1465 mul \mx, \mx, r11 1466 mul \my, \my, r11 1467 add \mx, \mx, r9 // mx, 8tap_h, 4tap_h 1468 add \my, \my, r10 // my, 8tap_v, 4tap_v 1469 1470.ifc \type, prep 1471 lsl \d_strd, \w, #1 1472.endif 1473 1474 vdup.16 q15, \bdmax // bitdepth_max 1475 clz \bdmax, \bdmax 1476 clz r9, \w 1477 sub \bdmax, \bdmax, #18 // intermediate_bits = clz(bitdepth_max) - 18 1478 tst \mx, #(0x7f << 14) 1479 sub r9, r9, #24 1480 add lr, \bdmax, #6 // 6 + intermediate_bits 1481 rsb r12, \bdmax, #6 // 6 - intermediate_bits 1482 movrel r11, X(mc_subpel_filters), -8 1483 bne L(\type\()_8tap_h) 1484 tst \my, #(0x7f << 14) 1485 bne L(\type\()_8tap_v) 1486 b \type\()_neon 1487 1488L(\type\()_8tap_h): 1489 cmp \w, #4 1490 ubfx r10, \mx, #7, #7 1491 and \mx, \mx, #0x7f 1492 it gt 1493 movgt \mx, r10 1494 tst \my, #(0x7f << 14) 1495 add \mx, r11, \mx, lsl #3 1496 bne L(\type\()_8tap_hv) 1497 1498 adr r10, L(\type\()_8tap_h_tbl) 1499 vdup.32 q14, r12 // 6 - intermediate_bits 1500 ldr r9, [r10, r9, lsl #2] 1501 vneg.s32 q14, q14 // -(6-intermediate_bits) 1502.ifc \type, put 1503 vdup.16 q13, \bdmax // intermediate_bits 1504.else 1505 vmov.i16 q13, #PREP_BIAS 1506.endif 1507 add r10, r10, r9 1508.ifc \type, put 1509 vneg.s16 q13, q13 // -intermediate_bits 1510.endif 1511 bx r10 1512 1513 .align 2 1514L(\type\()_8tap_h_tbl): 1515 .word 1280f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1516 .word 640f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1517 .word 320f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1518 .word 160f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1519 .word 80f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1520 .word 40f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1521 .word 20f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1522 152320: // 2xN h 1524.ifc \type, put 1525 add \mx, \mx, #2 1526 vld1.32 {d0[]}, [\mx] 1527 sub \src, \src, #2 1528 add \ds2, \dst, \d_strd 1529 add \sr2, \src, \s_strd 1530 lsl \d_strd, \d_strd, #1 1531 lsl \s_strd, \s_strd, #1 1532 vmovl.s8 q0, d0 15332: 1534 vld1.16 {q2}, [\src], \s_strd 1535 vld1.16 {q3}, [\sr2], \s_strd 1536 vext.8 d5, d4, d5, #2 1537 vext.8 d7, d6, d7, #2 1538 subs \h, \h, #2 1539 vtrn.32 d4, d6 1540 vtrn.32 d5, d7 1541 vmull.s16 q1, d4, d0[0] 1542 vmlal.s16 q1, d5, d0[1] 1543 vmlal.s16 q1, d6, d0[2] 1544 vmlal.s16 q1, d7, d0[3] 1545 vrshl.s32 q1, q1, q14 // -(6-intermediate_bits) 1546 vqmovun.s32 d2, q1 1547 vrshl.s16 d2, d2, d26 // -intermediate_bits 1548 vmin.u16 d2, d2, d30 1549 vst1.32 {d2[0]}, [\dst, :32], \d_strd 1550 vst1.32 {d2[1]}, [\ds2, :32], \d_strd 1551 bgt 2b 1552 pop {r4-r11,pc} 1553.endif 1554 155540: // 4xN h 1556 add \mx, \mx, #2 1557 vld1.32 {d0[]}, [\mx] 1558 sub \src, \src, #2 1559 add \ds2, \dst, \d_strd 1560 add \sr2, \src, \s_strd 1561 lsl \d_strd, \d_strd, #1 1562 lsl \s_strd, \s_strd, #1 1563 vmovl.s8 q0, d0 15644: 1565 vld1.16 {q8}, [\src], \s_strd 1566 vld1.16 {q11}, [\sr2], \s_strd 1567 vext.8 d18, d16, d17, #2 1568 vext.8 d19, d16, d17, #4 1569 vext.8 d20, d16, d17, #6 1570 vext.8 d24, d22, d23, #2 1571 vext.8 d25, d22, d23, #4 1572 vext.8 d21, d22, d23, #6 1573 subs \h, \h, #2 1574 vmull.s16 q2, d16, d0[0] 1575 vmlal.s16 q2, d18, d0[1] 1576 vmlal.s16 q2, d19, d0[2] 1577 vmlal.s16 q2, d20, d0[3] 1578 vmull.s16 q3, d22, d0[0] 1579 vmlal.s16 q3, d24, d0[1] 1580 vmlal.s16 q3, d25, d0[2] 1581 vmlal.s16 q3, d21, d0[3] 1582 vrshl.s32 q2, q2, q14 // -(6-intermediate_bits) 1583 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 1584.ifc \type, put 1585 vqmovun.s32 d4, q2 1586 vqmovun.s32 d5, q3 1587 vrshl.s16 q2, q2, q13 // -intermediate_bits 1588 vmin.u16 q2, q2, q15 1589.else 1590 vmovn.s32 d4, q2 1591 vmovn.s32 d5, q3 1592 vsub.i16 q2, q2, q13 // PREP_BIAS 1593.endif 1594 vst1.16 {d4}, [\dst, :64], \d_strd 1595 vst1.16 {d5}, [\ds2, :64], \d_strd 1596 bgt 4b 1597 pop {r4-r11,pc} 1598 159980: 1600160: 1601320: 1602640: 16031280: // 8xN, 16xN, 32xN, ... h 1604 vpush {q4-q5} 1605 vld1.8 {d0}, [\mx, :64] 1606 sub \src, \src, #6 1607 add \ds2, \dst, \d_strd 1608 add \sr2, \src, \s_strd 1609 lsl \s_strd, \s_strd, #1 1610 vmovl.s8 q0, d0 1611 1612 sub \s_strd, \s_strd, \w, lsl #1 1613 sub \s_strd, \s_strd, #16 1614.ifc \type, put 1615 lsl \d_strd, \d_strd, #1 1616 sub \d_strd, \d_strd, \w, lsl #1 1617.endif 161881: 1619 vld1.16 {q8, q9}, [\src]! 1620 vld1.16 {q10, q11}, [\sr2]! 1621 mov \mx, \w 1622 16238: 1624 vmull.s16 q1, d16, d0[0] 1625 vmull.s16 q2, d17, d0[0] 1626 vmull.s16 q3, d20, d0[0] 1627 vmull.s16 q4, d21, d0[0] 1628.irpc i, 1234567 1629 vext.8 q12, q8, q9, #(2*\i) 1630 vext.8 q5, q10, q11, #(2*\i) 1631.if \i < 4 1632 vmlal.s16 q1, d24, d0[\i] 1633 vmlal.s16 q2, d25, d0[\i] 1634 vmlal.s16 q3, d10, d0[\i] 1635 vmlal.s16 q4, d11, d0[\i] 1636.else 1637 vmlal.s16 q1, d24, d1[\i-4] 1638 vmlal.s16 q2, d25, d1[\i-4] 1639 vmlal.s16 q3, d10, d1[\i-4] 1640 vmlal.s16 q4, d11, d1[\i-4] 1641.endif 1642.endr 1643 subs \mx, \mx, #8 1644 vrshl.s32 q1, q1, q14 // -(6-intermediate_bits) 1645 vrshl.s32 q2, q2, q14 // -(6-intermediate_bits) 1646 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 1647 vrshl.s32 q4, q4, q14 // -(6-intermediate_bits) 1648.ifc \type, put 1649 vqmovun.s32 d2, q1 1650 vqmovun.s32 d3, q2 1651 vqmovun.s32 d4, q3 1652 vqmovun.s32 d5, q4 1653 vrshl.s16 q1, q1, q13 // -intermediate_bits 1654 vrshl.s16 q2, q2, q13 // -intermediate_bits 1655 vmin.u16 q1, q1, q15 1656 vmin.u16 q2, q2, q15 1657.else 1658 vmovn.s32 d2, q1 1659 vmovn.s32 d3, q2 1660 vmovn.s32 d4, q3 1661 vmovn.s32 d5, q4 1662 vsub.i16 q1, q1, q13 // PREP_BIAS 1663 vsub.i16 q2, q2, q13 // PREP_BIAS 1664.endif 1665 vst1.16 {q1}, [\dst, :128]! 1666 vst1.16 {q2}, [\ds2, :128]! 1667 ble 9f 1668 1669 vmov q8, q9 1670 vmov q10, q11 1671 vld1.16 {q9}, [\src]! 1672 vld1.16 {q11}, [\sr2]! 1673 b 8b 1674 16759: 1676 add \dst, \dst, \d_strd 1677 add \ds2, \ds2, \d_strd 1678 add \src, \src, \s_strd 1679 add \sr2, \sr2, \s_strd 1680 1681 subs \h, \h, #2 1682 bgt 81b 1683 vpop {q4-q5} 1684 pop {r4-r11,pc} 1685 1686 1687L(\type\()_8tap_v): 1688 cmp \h, #4 1689 ubfx r10, \my, #7, #7 1690 and \my, \my, #0x7f 1691 it gt 1692 movgt \my, r10 1693 add \my, r11, \my, lsl #3 1694 1695.ifc \type, prep 1696 vdup.32 q14, r12 // 6 - intermediate_bits 1697 vmov.i16 q15, #PREP_BIAS 1698.endif 1699 adr r10, L(\type\()_8tap_v_tbl) 1700 ldr r9, [r10, r9, lsl #2] 1701.ifc \type, prep 1702 vneg.s32 q14, q14 // -(6-intermediate_bits) 1703.endif 1704 add r10, r10, r9 1705 bx r10 1706 1707 .align 2 1708L(\type\()_8tap_v_tbl): 1709 .word 1280f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1710 .word 640f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1711 .word 320f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1712 .word 160f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1713 .word 80f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1714 .word 40f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1715 .word 20f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1716 171720: // 2xN v 1718.ifc \type, put 1719 bgt 28f 1720 1721 cmp \h, #2 1722 add \my, \my, #2 1723 vld1.32 {d0[]}, [\my] 1724 sub \src, \src, \s_strd 1725 add \ds2, \dst, \d_strd 1726 add \sr2, \src, \s_strd 1727 lsl \s_strd, \s_strd, #1 1728 lsl \d_strd, \d_strd, #1 1729 vmovl.s8 q0, d0 1730 1731 // 2x2 v 1732 load_32 \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1733 interleave_1_32 d1, d2, d3, d4, d5 1734 bgt 24f 1735 vmull_vmlal_4 q8, d1, d2, d3, d4 1736 vqrshrun_s32 6, q8, d16 1737 vmin_u16 d30, d16 1738 vst1_32 \d_strd, d16 1739 pop {r4-r11,pc} 1740 174124: // 2x4 v 1742 load_32 \sr2, \src, \s_strd, d6, d7 1743 interleave_1_32 d5, d6, d7 1744 vmull_vmlal_4 q8, d1, d2, d3, d4 1745 vmull_vmlal_4 q9, d3, d4, d5, d6 1746 vqrshrun_s32 6, q8, d16, q9, d17 1747 vmin_u16 q15, q8 1748 vst1_32 \d_strd, d16, d17 1749 pop {r4-r11,pc} 1750 175128: // 2x6, 2x8, 2x12, 2x16 v 1752 vld1.8 {d0}, [\my, :64] 1753 sub \sr2, \src, \s_strd, lsl #1 1754 add \ds2, \dst, \d_strd 1755 sub \src, \sr2, \s_strd 1756 lsl \d_strd, \d_strd, #1 1757 lsl \s_strd, \s_strd, #1 1758 vmovl.s8 q0, d0 1759 1760 load_32 \src, \sr2, \s_strd, d2, d3, d4, d5, d6, d7, d16 1761 interleave_1_32 d2, d3, d4, d5, d6 1762 interleave_1_32 d6, d7, d16 1763216: 1764 subs \h, \h, #4 1765 load_32 \sr2, \src, \s_strd, d17, d18, d19, d20 1766 interleave_1_32 d16, d17, d18, d19, d20 1767 vmull_vmlal_8 q13, d2, d3, d4, d5, d6, d7, d16, d17 1768 vmull_vmlal_8 q1, d4, d5, d6, d7, d16, d17, d18, d19 1769 vqrshrun_s32 6, q13, d26, q1, d27 1770 vmin_u16 q15, q13 1771 vst1_32 \d_strd, d26, d27 1772 ble 0f 1773 cmp \h, #2 1774 vmov q1, q3 1775 vmov q2, q8 1776 vmov q3, q9 1777 vmov d16, d20 1778 beq 26f 1779 b 216b 178026: 1781 load_32 \sr2, \src, \s_strd, d17, d18 1782 interleave_1_32 d16, d17, d18 1783 vmull_vmlal_8 q13, d2, d3, d4, d5, d6, d7, d16, d17 1784 vqrshrun_s32 6, q13, d26 1785 vmin_u16 d30, d26 1786 vst1_32 \d_strd, d26 17870: 1788 pop {r4-r11,pc} 1789.endif 1790 179140: 1792 bgt 480f 1793 1794 // 4x2, 4x4 v 1795 cmp \h, #2 1796 add \my, \my, #2 1797 vld1.32 {d0[]}, [\my] 1798 sub \src, \src, \s_strd 1799 add \ds2, \dst, \d_strd 1800 add \sr2, \src, \s_strd 1801 lsl \s_strd, \s_strd, #1 1802 lsl \d_strd, \d_strd, #1 1803 vmovl.s8 q0, d0 1804 1805 load_reg \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1806 vmull_vmlal_4 q8, d1, d2, d3, d4 1807 vmull_vmlal_4 q9, d2, d3, d4, d5 1808 shift_store_4 \type, \d_strd, q8, q9, d16, d17 1809 ble 0f 1810 load_reg \sr2, \src, \s_strd, d6, d7 1811 vmull_vmlal_4 q8, d3, d4, d5, d6 1812 vmull_vmlal_4 q9, d4, d5, d6, d7 1813 shift_store_4 \type, \d_strd, q8, q9, d16, d17 18140: 1815 pop {r4-r11,pc} 1816 1817480: // 4x6, 4x8, 4x12, 4x16 v 1818 vld1.8 {d0}, [\my, :64] 1819 sub \sr2, \src, \s_strd, lsl #1 1820 add \ds2, \dst, \d_strd 1821 sub \src, \sr2, \s_strd 1822 lsl \s_strd, \s_strd, #1 1823 lsl \d_strd, \d_strd, #1 1824 vmovl.s8 q0, d0 1825 1826 load_reg \src, \sr2, \s_strd, d16, d17, d18, d19, d20, d21, d22 1827 182848: 1829 subs \h, \h, #4 1830 load_reg \sr2, \src, \s_strd, d23, d24, d25, d26 1831 vmull_vmlal_8 q1, d16, d17, d18, d19, d20, d21, d22, d23 1832 vmull_vmlal_8 q2, d17, d18, d19, d20, d21, d22, d23, d24 1833 vmull_vmlal_8 q3, d18, d19, d20, d21, d22, d23, d24, d25 1834 vmull_vmlal_8 q8, d19, d20, d21, d22, d23, d24, d25, d26 1835 shift_store_4 \type, \d_strd, q1, q2, d2, d3, q3, q8, d4, d5 1836 ble 0f 1837 cmp \h, #2 1838 vmov q8, q10 1839 vmov q9, q11 1840 vmov q10, q12 1841 vmov d22, d26 1842 beq 46f 1843 b 48b 184446: 1845 load_reg \sr2, \src, \s_strd, d23, d24 1846 vmull_vmlal_8 q1, d16, d17, d18, d19, d20, d21, d22, d23 1847 vmull_vmlal_8 q2, d17, d18, d19, d20, d21, d22, d23, d24 1848 shift_store_4 \type, \d_strd, q1, q2, d2, d3 18490: 1850 pop {r4-r11,pc} 1851 185280: 1853 bgt 880f 1854 1855 // 8x2, 8x4 v 1856 cmp \h, #2 1857 add \my, \my, #2 1858 vld1.32 {d0[]}, [\my] 1859 sub \src, \src, \s_strd 1860 add \ds2, \dst, \d_strd 1861 add \sr2, \src, \s_strd 1862 lsl \s_strd, \s_strd, #1 1863 lsl \d_strd, \d_strd, #1 1864 vmovl.s8 q0, d0 1865 1866 load_reg \src, \sr2, \s_strd, q1, q2, q3, q8, q9 1867 vmull_vmlal_4 q10, d2, d4, d6, d16 1868 vmull_vmlal_4 q11, d3, d5, d7, d17 1869 vmull_vmlal_4 q12, d4, d6, d16, d18 1870 vmull_vmlal_4 q13, d5, d7, d17, d19 1871 shift_store_8 \type, \d_strd, q10, q11, d20, d21, q12, q13, d22, d23 1872 ble 0f 1873 load_reg \sr2, \src, \s_strd, q10, q11 1874 vmull_vmlal_4 q1, d6, d16, d18, d20 1875 vmull_vmlal_4 q2, d7, d17, d19, d21 1876 vmull_vmlal_4 q12, d16, d18, d20, d22 1877 vmull_vmlal_4 q13, d17, d19, d21, d23 1878 shift_store_8 \type, \d_strd, q1, q2, d2, d3, q12, q13, d4, d5 18790: 1880 pop {r4-r11,pc} 1881 1882880: // 8x6, 8x8, 8x16, 8x32 v 18831680: // 16x8, 16x16, ... 1884320: // 32x8, 32x16, ... 1885640: 18861280: 1887 vpush {q4-q7} 1888 vld1.8 {d0}, [\my, :64] 1889 sub \src, \src, \s_strd 1890 sub \src, \src, \s_strd, lsl #1 1891 vmovl.s8 q0, d0 1892 mov \my, \h 1893168: 1894 add \ds2, \dst, \d_strd 1895 add \sr2, \src, \s_strd 1896 lsl \s_strd, \s_strd, #1 1897 lsl \d_strd, \d_strd, #1 1898 1899 load_reg \src, \sr2, \s_strd, q5, q6, q7, q8, q9, q10, q11 1900 190188: 1902 subs \h, \h, #2 1903 load_reg \sr2, \src, \s_strd, q12, q13 1904 vmull_vmlal_8 q1, d10, d12, d14, d16, d18, d20, d22, d24 1905 vmull_vmlal_8 q2, d11, d13, d15, d17, d19, d21, d23, d25 1906 vmull_vmlal_8 q3, d12, d14, d16, d18, d20, d22, d24, d26 1907 vmull_vmlal_8 q4, d13, d15, d17, d19, d21, d23, d25, d27 1908 shift_store_8 \type, \d_strd, q1, q2, d2, d3, q3, q4, d4, d5 1909 ble 9f 1910 subs \h, \h, #2 1911 load_reg \sr2, \src, \s_strd, q1, q2 1912 vmull_vmlal_8 q3, d14, d16, d18, d20, d22, d24, d26, d2 1913 vmull_vmlal_8 q4, d15, d17, d19, d21, d23, d25, d27, d3 1914 vmull_vmlal_8 q5, d16, d18, d20, d22, d24, d26, d2, d4 1915 vmull_vmlal_8 q6, d17, d19, d21, d23, d25, d27, d3, d5 1916 shift_store_8 \type, \d_strd, q3, q4, d6, d7, q5, q6, d8, d9 1917 ble 9f 1918 vmov q5, q9 1919 vmov q6, q10 1920 vmov q7, q11 1921 vmov q8, q12 1922 vmov q9, q13 1923 vmov q10, q1 1924 vmov q11, q2 1925 b 88b 19269: 1927 subs \w, \w, #8 1928 ble 0f 1929 asr \s_strd, \s_strd, #1 1930 asr \d_strd, \d_strd, #1 1931 mls \src, \s_strd, \my, \src 1932 mls \dst, \d_strd, \my, \dst 1933 sub \src, \src, \s_strd, lsl #3 1934 mov \h, \my 1935 add \src, \src, #16 1936 add \dst, \dst, #16 1937 b 168b 19380: 1939 vpop {q4-q7} 1940 pop {r4-r11,pc} 1941 1942160: 1943 bgt 1680b 1944 1945 // 16x2, 16x4 v 1946 vpush {q6-q7} 1947 add \my, \my, #2 1948 vld1.32 {d0[]}, [\my] 1949 sub \src, \src, \s_strd 1950 vmovl.s8 q0, d0 1951 1952 load_16s16 \src, \src, \s_strd, q6, q7, q8, q9, q10, q11 195316: 1954 load_16s16 \src, \src, \s_strd, q12, q13 1955 subs \h, \h, #1 1956 vmull_vmlal_4 q1, d12, d16, d20, d24 1957 vmull_vmlal_4 q2, d13, d17, d21, d25 1958 vmull_vmlal_4 q3, d14, d18, d22, d26 1959 vmull_vmlal_4 q6, d15, d19, d23, d27 1960 shift_store_16 \type, \d_strd, q1, q2, d2, d3, q3, q6, d4, d5 1961 ble 0f 1962 vmov q6, q8 1963 vmov q7, q9 1964 vmov q8, q10 1965 vmov q9, q11 1966 vmov q10, q12 1967 vmov q11, q13 1968 b 16b 19690: 1970 vpop {q6-q7} 1971 pop {r4-r11,pc} 1972 1973 1974L(\type\()_8tap_hv): 1975 cmp \h, #4 1976 ubfx r10, \my, #7, #7 1977 and \my, \my, #0x7f 1978 it gt 1979 movgt \my, r10 19804: 1981 add \my, r11, \my, lsl #3 1982 1983 adr r10, L(\type\()_8tap_hv_tbl) 1984 neg r12, r12 // -(6-intermediate_bits) 1985 ldr r9, [r10, r9, lsl #2] 1986 vdup.32 q14, r12 // -(6-intermediate_bits) 1987.ifc \type, put 1988 neg r8, lr // -(6+intermeidate_bits) 1989.else 1990 vmov.i16 q13, #PREP_BIAS 1991.endif 1992 add r10, r10, r9 1993.ifc \type, put 1994 vdup.32 q13, r8 // -(6+intermediate_bits) 1995.endif 1996 bx r10 1997 1998 .align 2 1999L(\type\()_8tap_hv_tbl): 2000 .word 1280f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 2001 .word 640f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 2002 .word 320f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 2003 .word 160f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 2004 .word 80f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 2005 .word 40f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 2006 .word 20f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 2007 200820: 2009.ifc \type, put 2010 add \mx, \mx, #2 2011 vld1.32 {d0[]}, [\mx] 2012 bgt 280f 2013 add \my, \my, #2 2014 vld1.32 {d2[]}, [\my] 2015 2016 // 2x2, 2x4 hv 2017 sub \sr2, \src, #2 2018 sub \src, \sr2, \s_strd 2019 add \ds2, \dst, \d_strd 2020 lsl \s_strd, \s_strd, #1 2021 lsl \d_strd, \d_strd, #1 2022 vmovl.s8 q0, d0 2023 vmovl.s8 q1, d2 2024 2025 vld1.16 {q11}, [\src], \s_strd 2026 vext.8 d24, d22, d23, #2 2027 vmull.s16 q11, d22, d0 2028 vmull.s16 q12, d24, d0 2029 vpadd.s32 d22, d22, d23 2030 vpadd.s32 d23, d24, d25 2031 vpadd.s32 d22, d22, d23 2032 vrshl.s32 d16, d22, d28 // -(6-intermediate_bits) 2033 vmovn.i32 d16, q8 2034 bl L(\type\()_8tap_filter_2) 2035 2036 vext.8 d16, d16, d16, #4 2037 vext.8 d16, d16, d24, #4 2038 vmov d17, d24 2039 20402: 2041 bl L(\type\()_8tap_filter_2) 2042 2043 vext.8 d18, d17, d24, #4 2044 vmull.s16 q2, d16, d2[0] 2045 vmlal.s16 q2, d17, d2[1] 2046 vmlal.s16 q2, d18, d2[2] 2047 vmlal.s16 q2, d24, d2[3] 2048 2049 vrshl.s32 q2, q2, q13 // -(6+intermediate_bits) 2050 vqmovun.s32 d4, q2 2051 vmin.u16 d4, d4, d30 2052 subs \h, \h, #2 2053 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2054 vst1.32 {d4[1]}, [\ds2, :32], \d_strd 2055 ble 0f 2056 vmov d16, d18 2057 vmov d17, d24 2058 b 2b 2059 2060280: // 2x8, 2x16, 2x32 hv 2061 vld1.8 {d2}, [\my, :64] 2062 sub \src, \src, #2 2063 sub \sr2, \src, \s_strd, lsl #1 2064 sub \src, \sr2, \s_strd 2065 add \ds2, \dst, \d_strd 2066 lsl \s_strd, \s_strd, #1 2067 lsl \d_strd, \d_strd, #1 2068 vmovl.s8 q0, d0 2069 vmovl.s8 q1, d2 2070 2071 vld1.16 {q11}, [\src], \s_strd 2072 vext.8 d24, d22, d23, #2 2073 vmull.s16 q11, d22, d0 2074 vmull.s16 q12, d24, d0 2075 vpadd.s32 d22, d22, d23 2076 vpadd.s32 d23, d24, d25 2077 vpadd.s32 d22, d22, d23 2078 vrshl.s32 d16, d22, d28 // -(6-intermediate_bits) 2079 vmovn.i32 d16, q8 2080 2081 bl L(\type\()_8tap_filter_2) 2082 2083 vext.8 d16, d16, d16, #4 2084 vext.8 d16, d16, d24, #4 2085 vmov d17, d24 2086 bl L(\type\()_8tap_filter_2) 2087 vext.8 d18, d17, d24, #4 2088 vmov d19, d24 2089 bl L(\type\()_8tap_filter_2) 2090 vext.8 d20, d19, d24, #4 2091 vmov d21, d24 2092 209328: 2094 bl L(\type\()_8tap_filter_2) 2095 vext.8 d22, d21, d24, #4 2096 vmull.s16 q3, d16, d2[0] 2097 vmlal.s16 q3, d17, d2[1] 2098 vmlal.s16 q3, d18, d2[2] 2099 vmlal.s16 q3, d19, d2[3] 2100 vmlal.s16 q3, d20, d3[0] 2101 vmlal.s16 q3, d21, d3[1] 2102 vmlal.s16 q3, d22, d3[2] 2103 vmlal.s16 q3, d24, d3[3] 2104 2105 vrshl.s32 q3, q3, q13 // -(6+intermediate_bits) 2106 vqmovun.s32 d6, q3 2107 vmin.u16 d6, d6, d30 2108 subs \h, \h, #2 2109 vst1.32 {d6[0]}, [\dst, :32], \d_strd 2110 vst1.32 {d6[1]}, [\ds2, :32], \d_strd 2111 ble 0f 2112 vmov q8, q9 2113 vmov q9, q10 2114 vmov d20, d22 2115 vmov d21, d24 2116 b 28b 21170: 2118 pop {r4-r11,pc} 2119 2120L(\type\()_8tap_filter_2): 2121 vld1.16 {q11}, [\sr2], \s_strd 2122 vld1.16 {q12}, [\src], \s_strd 2123 vext.8 d23, d22, d23, #2 2124 vext.8 d25, d24, d25, #2 2125 vtrn.32 q11, q12 2126 vmull.s16 q3, d22, d0[0] 2127 vmlal.s16 q3, d23, d0[1] 2128 vmlal.s16 q3, d24, d0[2] 2129 vmlal.s16 q3, d25, d0[3] 2130 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 2131 vmovn.i32 d24, q3 2132 bx lr 2133.endif 2134 213540: 2136 add \mx, \mx, #2 2137 vld1.32 {d0[]}, [\mx] 2138 bgt 480f 2139 add \my, \my, #2 2140 vld1.32 {d2[]}, [\my] 2141 sub \sr2, \src, #2 2142 sub \src, \sr2, \s_strd 2143 add \ds2, \dst, \d_strd 2144 lsl \s_strd, \s_strd, #1 2145 lsl \d_strd, \d_strd, #1 2146 vmovl.s8 q0, d0 2147 vmovl.s8 q1, d2 2148 2149 // 4x2, 4x4 hv 2150 vld1.16 {q11}, [\src], \s_strd 2151 vext.8 d24, d22, d23, #2 2152 vext.8 d25, d22, d23, #4 2153 vext.8 d23, d22, d23, #6 2154 vmull.s16 q10, d22, d0[0] 2155 vmlal.s16 q10, d24, d0[1] 2156 vmlal.s16 q10, d25, d0[2] 2157 vmlal.s16 q10, d23, d0[3] 2158 vrshl.s32 q10, q10, q14 // -(6-intermediate_bits) 2159 vmovn.i32 d17, q10 2160 2161 bl L(\type\()_8tap_filter_4) 2162 vmov q9, q12 2163 21644: 2165 bl L(\type\()_8tap_filter_4) 2166 vmull.s16 q2, d17, d2[0] 2167 vmlal.s16 q2, d18, d2[1] 2168 vmlal.s16 q2, d19, d2[2] 2169 vmlal.s16 q2, d24, d2[3] 2170 vmull.s16 q3, d18, d2[0] 2171 vmlal.s16 q3, d19, d2[1] 2172 vmlal.s16 q3, d24, d2[2] 2173 vmlal.s16 q3, d25, d2[3] 2174.ifc \type, put 2175 vrshl.s32 q2, q2, q13 // -(6+intermediate_bits) 2176 vrshl.s32 q3, q3, q13 // -(6+intermediate_bits) 2177 vqmovun.s32 d4, q2 2178 vqmovun.s32 d5, q3 2179 vmin.u16 q2, q2, q15 2180.else 2181 vrshrn.i32 d4, q2, #6 2182 vrshrn.i32 d5, q3, #6 2183 vsub.i16 q2, q2, q13 // PREP_BIAS 2184.endif 2185 subs \h, \h, #2 2186 2187 vst1.16 {d4}, [\dst, :64], \d_strd 2188 vst1.16 {d5}, [\ds2, :64], \d_strd 2189 ble 0f 2190 vmov d17, d19 2191 vmov q9, q12 2192 b 4b 21930: 2194 pop {r4-r11,pc} 2195 2196480: // 4x8, 4x16, 4x32 hv 2197 vpush {d13-d15} 2198 vld1.8 {d2}, [\my, :64] 2199 sub \src, \src, #2 2200 sub \sr2, \src, \s_strd, lsl #1 2201 sub \src, \sr2, \s_strd 2202 add \ds2, \dst, \d_strd 2203 lsl \s_strd, \s_strd, #1 2204 lsl \d_strd, \d_strd, #1 2205 vmovl.s8 q0, d0 2206 vmovl.s8 q1, d2 2207 2208 vld1.16 {q11}, [\src], \s_strd 2209 vext.8 d24, d22, d23, #2 2210 vext.8 d25, d22, d23, #4 2211 vext.8 d23, d22, d23, #6 2212 vmull.s16 q10, d22, d0[0] 2213 vmlal.s16 q10, d24, d0[1] 2214 vmlal.s16 q10, d25, d0[2] 2215 vmlal.s16 q10, d23, d0[3] 2216 vrshl.s32 q10, q10, q14 // -(6-intermediate_bits) 2217 vmovn.i32 d13, q10 2218 2219 bl L(\type\()_8tap_filter_4) 2220 vmov q7, q12 2221 bl L(\type\()_8tap_filter_4) 2222 vmov q8, q12 2223 bl L(\type\()_8tap_filter_4) 2224 vmov q9, q12 2225 222648: 2227 bl L(\type\()_8tap_filter_4) 2228 vmull.s16 q2, d13, d2[0] 2229 vmlal.s16 q2, d14, d2[1] 2230 vmlal.s16 q2, d15, d2[2] 2231 vmlal.s16 q2, d16, d2[3] 2232 vmlal.s16 q2, d17, d3[0] 2233 vmlal.s16 q2, d18, d3[1] 2234 vmlal.s16 q2, d19, d3[2] 2235 vmlal.s16 q2, d24, d3[3] 2236 vmull.s16 q3, d14, d2[0] 2237 vmlal.s16 q3, d15, d2[1] 2238 vmlal.s16 q3, d16, d2[2] 2239 vmlal.s16 q3, d17, d2[3] 2240 vmlal.s16 q3, d18, d3[0] 2241 vmlal.s16 q3, d19, d3[1] 2242 vmlal.s16 q3, d24, d3[2] 2243 vmlal.s16 q3, d25, d3[3] 2244.ifc \type, put 2245 vrshl.s32 q2, q2, q13 // -(6+intermediate_bits) 2246 vrshl.s32 q3, q3, q13 // -(6+intermediate_bits) 2247 vqmovun.s32 d4, q2 2248 vqmovun.s32 d5, q3 2249 vmin.u16 q2, q2, q15 2250.else 2251 vrshrn.i32 d4, q2, #6 2252 vrshrn.i32 d5, q3, #6 2253 vsub.i16 q2, q2, q13 // PREP_BIAS 2254.endif 2255 subs \h, \h, #2 2256 vst1.16 {d4}, [\dst, :64], \d_strd 2257 vst1.16 {d5}, [\ds2, :64], \d_strd 2258 ble 0f 2259 vmov d13, d15 2260 vmov q7, q8 2261 vmov q8, q9 2262 vmov q9, q12 2263 b 48b 22640: 2265 vpop {d13-d15} 2266 pop {r4-r11,pc} 2267 2268L(\type\()_8tap_filter_4): 2269 vld1.16 {q10}, [\sr2], \s_strd 2270 vld1.16 {q11}, [\src], \s_strd 2271 vext.8 d24, d20, d21, #2 2272 vext.8 d25, d20, d21, #4 2273 vext.8 d21, d20, d21, #6 2274 vmull.s16 q3, d20, d0[0] 2275 vmlal.s16 q3, d24, d0[1] 2276 vmlal.s16 q3, d25, d0[2] 2277 vmlal.s16 q3, d21, d0[3] 2278 vext.8 d24, d22, d23, #2 2279 vext.8 d25, d22, d23, #4 2280 vext.8 d23, d22, d23, #6 2281 vmull.s16 q10, d22, d0[0] 2282 vmlal.s16 q10, d24, d0[1] 2283 vmlal.s16 q10, d25, d0[2] 2284 vmlal.s16 q10, d23, d0[3] 2285 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 2286 vrshl.s32 q10, q10, q14 // -(6-intermediate_bits) 2287 vmovn.i32 d24, q3 2288 vmovn.i32 d25, q10 2289 bx lr 2290 229180: 2292160: 2293320: 2294 bgt 880f 2295 add \my, \my, #2 2296 vld1.8 {d0}, [\mx, :64] 2297 vld1.32 {d2[]}, [\my] 2298 sub \src, \src, #6 2299 sub \src, \src, \s_strd 2300 vmovl.s8 q0, d0 2301 vmovl.s8 q1, d2 2302 mov \my, \h 2303 2304164: // 8x2, 8x4, 16x2, 16x4, 32x2, 32x4 hv 2305 add \ds2, \dst, \d_strd 2306 add \sr2, \src, \s_strd 2307 lsl \d_strd, \d_strd, #1 2308 lsl \s_strd, \s_strd, #1 2309 2310 vld1.16 {q11, q12}, [\src], \s_strd 2311 vmull.s16 q2, d22, d0[0] 2312 vmull.s16 q3, d23, d0[0] 2313 vdup.32 q14, r12 // -(6-intermediate_bits) 2314.irpc i, 1234567 2315 vext.8 q10, q11, q12, #(2*\i) 2316.if \i < 4 2317 vmlal.s16 q2, d20, d0[\i] 2318 vmlal.s16 q3, d21, d0[\i] 2319.else 2320 vmlal.s16 q2, d20, d1[\i - 4] 2321 vmlal.s16 q3, d21, d1[\i - 4] 2322.endif 2323.endr 2324 vrshl.s32 q2, q2, q14 // -(6-intermediate_bits) 2325 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 2326 vmovn.i32 d16, q2 2327 vmovn.i32 d17, q3 2328 2329 bl L(\type\()_8tap_filter_8) 2330 vmov q9, q11 2331 vmov q10, q12 2332 23338: 2334 bl L(\type\()_8tap_filter_8) 2335 vmull.s16 q2, d16, d2[0] 2336 vmull.s16 q3, d17, d2[0] 2337 vmull.s16 q13, d18, d2[0] 2338 vmull.s16 q14, d19, d2[0] 2339.ifc \type, put 2340 vdup.32 q8, r8 // -(6+intermediate_bits) 2341.endif 2342 vmlal.s16 q2, d18, d2[1] 2343 vmlal.s16 q3, d19, d2[1] 2344 vmlal.s16 q13, d20, d2[1] 2345 vmlal.s16 q14, d21, d2[1] 2346 vmlal.s16 q2, d20, d2[2] 2347 vmlal.s16 q3, d21, d2[2] 2348 vmlal.s16 q13, d22, d2[2] 2349 vmlal.s16 q14, d23, d2[2] 2350 vmlal.s16 q2, d22, d2[3] 2351 vmlal.s16 q3, d23, d2[3] 2352 vmlal.s16 q13, d24, d2[3] 2353 vmlal.s16 q14, d25, d2[3] 2354.ifc \type, put 2355 vdup.16 q9, \bdmax // bitdepth_max 2356 vrshl.s32 q2, q2, q8 // -(6+intermediate_bits) 2357 vrshl.s32 q3, q3, q8 // -(6+intermediate_bits) 2358 vrshl.s32 q13, q13, q8 // -(6+intermediate_bits) 2359 vrshl.s32 q14, q14, q8 // -(6+intermediate_bits) 2360 vqmovun.s32 d4, q2 2361 vqmovun.s32 d5, q3 2362 vqmovun.s32 d6, q13 2363 vqmovun.s32 d7, q14 2364 vmin.u16 q2, q2, q15 2365 vmin.u16 q3, q3, q15 2366.else 2367 vmov.i16 q9, #PREP_BIAS 2368 vrshrn.i32 d4, q2, #6 2369 vrshrn.i32 d5, q3, #6 2370 vrshrn.i32 d6, q13, #6 2371 vrshrn.i32 d7, q14, #6 2372 vsub.i16 q2, q2, q9 // PREP_BIAS 2373 vsub.i16 q3, q3, q9 // PREP_BIAS 2374.endif 2375 subs \h, \h, #2 2376 vst1.16 {q2}, [\dst, :128], \d_strd 2377 vst1.16 {q3}, [\ds2, :128], \d_strd 2378 ble 9f 2379 vmov q8, q10 2380 vmov q9, q11 2381 vmov q10, q12 2382 b 8b 23839: 2384 subs \w, \w, #8 2385 ble 0f 2386 asr \s_strd, \s_strd, #1 2387 asr \d_strd, \d_strd, #1 2388 mls \src, \s_strd, \my, \src 2389 mls \dst, \d_strd, \my, \dst 2390 sub \src, \src, \s_strd, lsl #2 2391 mov \h, \my 2392 add \src, \src, #16 2393 add \dst, \dst, #16 2394 b 164b 23950: 2396 pop {r4-r11,pc} 2397 2398880: // 8x8, 8x16, ..., 16x8, ..., 32x8, ... hv 2399640: 24001280: 2401 vpush {q4-q7} 2402 vld1.8 {d0}, [\mx, :64] 2403 vld1.8 {d2}, [\my, :64] 2404 sub \src, \src, #6 2405 sub \src, \src, \s_strd 2406 sub \src, \src, \s_strd, lsl #1 2407 vmovl.s8 q0, d0 2408 vmovl.s8 q1, d2 2409 mov \my, \h 2410 2411168: 2412 add \ds2, \dst, \d_strd 2413 add \sr2, \src, \s_strd 2414 lsl \d_strd, \d_strd, #1 2415 lsl \s_strd, \s_strd, #1 2416 2417 vld1.16 {q11, q12}, [\src], \s_strd 2418 vmull.s16 q2, d22, d0[0] 2419 vmull.s16 q3, d23, d0[0] 2420 vdup.32 q14, r12 // -(6-intermediate_bits) 2421.irpc i, 1234567 2422 vext.8 q10, q11, q12, #(2*\i) 2423.if \i < 4 2424 vmlal.s16 q2, d20, d0[\i] 2425 vmlal.s16 q3, d21, d0[\i] 2426.else 2427 vmlal.s16 q2, d20, d1[\i - 4] 2428 vmlal.s16 q3, d21, d1[\i - 4] 2429.endif 2430.endr 2431 vrshl.s32 q2, q2, q14 // -(6-intermediate_bits) 2432 vrshl.s32 q3, q3, q14 // -(6-intermediate_bits) 2433 vmovn.i32 d8, q2 2434 vmovn.i32 d9, q3 2435 2436 bl L(\type\()_8tap_filter_8) 2437 vmov q5, q11 2438 vmov q6, q12 2439 bl L(\type\()_8tap_filter_8) 2440 vmov q7, q11 2441 vmov q8, q12 2442 bl L(\type\()_8tap_filter_8) 2443 vmov q9, q11 2444 vmov q10, q12 2445 244688: 2447 bl L(\type\()_8tap_filter_8) 2448 vmull.s16 q2, d8, d2[0] 2449 vmull.s16 q3, d9, d2[0] 2450 vmull.s16 q13, d10, d2[0] 2451 vmull.s16 q14, d11, d2[0] 2452.ifc \type, put 2453 vdup.32 q4, r8 // -(6+intermediate_bits) 2454.endif 2455 vmlal.s16 q2, d10, d2[1] 2456 vmlal.s16 q3, d11, d2[1] 2457 vmlal.s16 q13, d12, d2[1] 2458 vmlal.s16 q14, d13, d2[1] 2459 vmlal.s16 q2, d12, d2[2] 2460 vmlal.s16 q3, d13, d2[2] 2461 vmlal.s16 q13, d14, d2[2] 2462 vmlal.s16 q14, d15, d2[2] 2463 vmlal.s16 q2, d14, d2[3] 2464 vmlal.s16 q3, d15, d2[3] 2465 vmlal.s16 q13, d16, d2[3] 2466 vmlal.s16 q14, d17, d2[3] 2467 vmlal.s16 q2, d16, d3[0] 2468 vmlal.s16 q3, d17, d3[0] 2469 vmlal.s16 q13, d18, d3[0] 2470 vmlal.s16 q14, d19, d3[0] 2471 vmlal.s16 q2, d18, d3[1] 2472 vmlal.s16 q3, d19, d3[1] 2473 vmlal.s16 q13, d20, d3[1] 2474 vmlal.s16 q14, d21, d3[1] 2475 vmlal.s16 q2, d20, d3[2] 2476 vmlal.s16 q3, d21, d3[2] 2477 vmlal.s16 q13, d22, d3[2] 2478 vmlal.s16 q14, d23, d3[2] 2479 vmlal.s16 q2, d22, d3[3] 2480 vmlal.s16 q3, d23, d3[3] 2481 vmlal.s16 q13, d24, d3[3] 2482 vmlal.s16 q14, d25, d3[3] 2483.ifc \type, put 2484 vrshl.s32 q2, q2, q4 // -(6+intermediate_bits) 2485 vrshl.s32 q3, q3, q4 // -(6+intermediate_bits) 2486 vrshl.s32 q13, q13, q4 // -(6+intermediate_bits) 2487 vrshl.s32 q14, q14, q4 // -(6+intermediate_bits) 2488 vqmovun.s32 d4, q2 2489 vqmovun.s32 d5, q3 2490 vqmovun.s32 d6, q13 2491 vqmovun.s32 d7, q14 2492 vmin.u16 q2, q2, q15 2493 vmin.u16 q3, q3, q15 2494.else 2495 vmov.i16 q5, #PREP_BIAS 2496 vrshrn.i32 d4, q2, #6 2497 vrshrn.i32 d5, q3, #6 2498 vrshrn.i32 d6, q13, #6 2499 vrshrn.i32 d7, q14, #6 2500 vsub.i16 q2, q2, q5 // PREP_BIAS 2501 vsub.i16 q3, q3, q5 // PREP_BIAS 2502.endif 2503 subs \h, \h, #2 2504 vst1.16 {q2}, [\dst, :128], \d_strd 2505 vst1.16 {q3}, [\ds2, :128], \d_strd 2506 ble 9f 2507 vmov q4, q6 2508 vmov q5, q7 2509 vmov q6, q8 2510 vmov q7, q9 2511 vmov q8, q10 2512 vmov q9, q11 2513 vmov q10, q12 2514 b 88b 25159: 2516 subs \w, \w, #8 2517 ble 0f 2518 asr \s_strd, \s_strd, #1 2519 asr \d_strd, \d_strd, #1 2520 mls \src, \s_strd, \my, \src 2521 mls \dst, \d_strd, \my, \dst 2522 sub \src, \src, \s_strd, lsl #3 2523 mov \h, \my 2524 add \src, \src, #16 2525 add \dst, \dst, #16 2526 b 168b 25270: 2528 vpop {q4-q7} 2529 pop {r4-r11,pc} 2530 2531L(\type\()_8tap_filter_8): 2532 vld1.16 {q13, q14}, [\sr2], \s_strd 2533 vmull.s16 q2, d26, d0[0] 2534 vmull.s16 q3, d27, d0[0] 2535.irpc i, 1234567 2536 vext.8 q12, q13, q14, #(2*\i) 2537.if \i < 4 2538 vmlal.s16 q2, d24, d0[\i] 2539 vmlal.s16 q3, d25, d0[\i] 2540.else 2541 vmlal.s16 q2, d24, d1[\i - 4] 2542 vmlal.s16 q3, d25, d1[\i - 4] 2543.endif 2544.endr 2545 vdup.32 q12, r12 // -(6-intermediate_bits) 2546 vld1.16 {q13, q14}, [\src], \s_strd 2547 vrshl.s32 q2, q2, q12 // -(6-intermediate_bits) 2548 vrshl.s32 q3, q3, q12 // -(6-intermediate_bits) 2549 vmovn.i32 d4, q2 2550 vmovn.i32 d5, q3 2551 2552 vmull.s16 q3, d26, d0[0] 2553 vmull.s16 q11, d27, d0[0] 2554.irpc i, 1234567 2555 vext.8 q12, q13, q14, #(2*\i) 2556.if \i < 4 2557 vmlal.s16 q3, d24, d0[\i] 2558 vmlal.s16 q11, d25, d0[\i] 2559.else 2560 vmlal.s16 q3, d24, d1[\i - 4] 2561 vmlal.s16 q11, d25, d1[\i - 4] 2562.endif 2563.endr 2564 vdup.32 q13, r12 // -(6-intermediate_bits) 2565 vrshl.s32 q3, q3, q13 // -(6-intermediate_bits) 2566 vrshl.s32 q11, q11, q13 // -(6-intermediate_bits) 2567 2568 vmovn.i32 d24, q3 2569 vmovn.i32 d25, q11 2570 vmov q11, q2 2571 bx lr 2572endfunc 2573 2574function \type\()_bilin_16bpc_neon, export=1 2575 push {r4-r11,lr} 2576 ldrd r4, r5, [sp, #36] 2577 ldrd r6, r7, [sp, #44] 2578.ifc \bdmax, r8 2579 ldr r8, [sp, #52] 2580.endif 2581 vdup.16 q1, \mx 2582 vdup.16 q3, \my 2583 rsb r9, \mx, #16 2584 rsb r10, \my, #16 2585 vdup.16 q0, r9 2586 vdup.16 q2, r10 2587.ifc \type, prep 2588 lsl \d_strd, \w, #1 2589.endif 2590 clz \bdmax, \bdmax // bitdepth_max 2591 clz r9, \w 2592 sub \bdmax, \bdmax, #18 // intermediate_bits = clz(bitdepth_max) - 18 2593 cmp \mx, #0 2594 sub r9, r9, #24 2595 rsb r11, \bdmax, #4 // 4 - intermediate_bits 2596 add r12, \bdmax, #4 // 4 + intermediate_bits 2597 bne L(\type\()_bilin_h) 2598 cmp \my, #0 2599 bne L(\type\()_bilin_v) 2600 b \type\()_neon 2601 2602L(\type\()_bilin_h): 2603 cmp \my, #0 2604 bne L(\type\()_bilin_hv) 2605 2606 adr r10, L(\type\()_bilin_h_tbl) 2607 vdup.16 q15, r11 // 4 - intermediate_bits 2608 ldr r9, [r10, r9, lsl #2] 2609 vneg.s16 q15, q15 // -(4-intermediate_bits) 2610.ifc \type, put 2611 vdup.16 q14, \bdmax // intermediate_bits 2612.else 2613 vmov.i16 q14, #PREP_BIAS 2614.endif 2615 add r10, r10, r9 2616.ifc \type, put 2617 vneg.s16 q14, q14 // -intermediate_bits 2618.endif 2619 bx r10 2620 2621 .align 2 2622L(\type\()_bilin_h_tbl): 2623 .word 1280f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2624 .word 640f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2625 .word 320f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2626 .word 160f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2627 .word 80f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2628 .word 40f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2629 .word 20f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2630 263120: // 2xN h 2632.ifc \type, put 2633 add \ds2, \dst, \d_strd 2634 add \sr2, \src, \s_strd 2635 lsl \d_strd, \d_strd, #1 2636 lsl \s_strd, \s_strd, #1 26372: 2638 vld1.16 {d16}, [\src], \s_strd 2639 vld1.16 {d18}, [\sr2], \s_strd 2640 vext.8 d17, d16, d16, #2 2641 vext.8 d19, d18, d18, #2 2642 vtrn.32 d16, d18 2643 vtrn.32 d17, d19 2644 subs \h, \h, #2 2645 vmul.i16 d16, d16, d0 2646 vmla.i16 d16, d17, d2 2647 vrshl.u16 d16, d16, d30 2648 vrshl.u16 d16, d16, d28 2649 vst1.32 {d16[0]}, [\dst, :32], \d_strd 2650 vst1.32 {d16[1]}, [\ds2, :32], \d_strd 2651 bgt 2b 2652 pop {r4-r11,pc} 2653.endif 2654 265540: // 4xN h 2656 add \ds2, \dst, \d_strd 2657 add \sr2, \src, \s_strd 2658 lsl \d_strd, \d_strd, #1 2659 lsl \s_strd, \s_strd, #1 26604: 2661 vld1.16 {q8}, [\src], \s_strd 2662 vld1.16 {q10}, [\sr2], \s_strd 2663 vext.8 q9, q8, q8, #2 2664 vext.8 q11, q10, q10, #2 2665 vmov d17, d20 2666 vmov d19, d22 2667 subs \h, \h, #2 2668 vmul.i16 q8, q8, q0 2669 vmla.i16 q8, q9, q1 2670 vrshl.u16 q8, q8, q15 2671.ifc \type, put 2672 vrshl.u16 q8, q8, q14 2673.else 2674 vsub.i16 q8, q8, q14 2675.endif 2676 vst1.16 {d16}, [\dst, :64], \d_strd 2677 vst1.16 {d17}, [\ds2, :64], \d_strd 2678 bgt 4b 2679 pop {r4-r11,pc} 2680 268180: // 8xN h 2682 add \ds2, \dst, \d_strd 2683 add \sr2, \src, \s_strd 2684 lsl \d_strd, \d_strd, #1 2685 lsl \s_strd, \s_strd, #1 26868: 2687 vld1.16 {d16, d17, d18}, [\src], \s_strd 2688 vld1.16 {d20, d21, d22}, [\sr2], \s_strd 2689 vext.8 q9, q8, q9, #2 2690 vext.8 q11, q10, q11, #2 2691 subs \h, \h, #2 2692 vmul.i16 q8, q8, q0 2693 vmla.i16 q8, q9, q1 2694 vmul.i16 q10, q10, q0 2695 vmla.i16 q10, q11, q1 2696 vrshl.u16 q8, q8, q15 2697 vrshl.u16 q10, q10, q15 2698.ifc \type, put 2699 vrshl.u16 q8, q8, q14 2700 vrshl.u16 q10, q10, q14 2701.else 2702 vsub.i16 q8, q8, q14 2703 vsub.i16 q10, q10, q14 2704.endif 2705 vst1.16 {q8}, [\dst, :128], \d_strd 2706 vst1.16 {q10}, [\ds2, :128], \d_strd 2707 bgt 8b 2708 pop {r4-r11,pc} 2709160: 2710320: 2711640: 27121280: // 16xN, 32xN, ... h 2713 vpush {q4-q7} 2714 add \ds2, \dst, \d_strd 2715 add \sr2, \src, \s_strd 2716 lsl \s_strd, \s_strd, #1 2717 2718 sub \s_strd, \s_strd, \w, lsl #1 2719 sub \s_strd, \s_strd, #16 2720.ifc \type, put 2721 lsl \d_strd, \d_strd, #1 2722 sub \d_strd, \d_strd, \w, lsl #1 2723.endif 2724161: 2725 vld1.16 {q4}, [\src]! 2726 vld1.16 {q9}, [\sr2]! 2727 mov \mx, \w 2728 272916: 2730 vld1.16 {q5, q6}, [\src]! 2731 vld1.16 {q10, q11}, [\sr2]! 2732 vext.8 q7, q4, q5, #2 2733 vext.8 q8, q5, q6, #2 2734 vext.8 q12, q9, q10, #2 2735 vext.8 q13, q10, q11, #2 2736 vmul.i16 q4, q4, q0 2737 vmla.i16 q4, q7, q1 2738 vmul.i16 q5, q5, q0 2739 vmla.i16 q5, q8, q1 2740 vmul.i16 q9, q9, q0 2741 vmla.i16 q9, q12, q1 2742 vmul.i16 q10, q10, q0 2743 vmla.i16 q10, q13, q1 2744 vrshl.u16 q4, q4, q15 2745 vrshl.u16 q5, q5, q15 2746 vrshl.u16 q9, q9, q15 2747 vrshl.u16 q10, q10, q15 2748 subs \mx, \mx, #16 2749.ifc \type, put 2750 vrshl.u16 q4, q4, q14 2751 vrshl.u16 q5, q5, q14 2752 vrshl.u16 q9, q9, q14 2753 vrshl.u16 q10, q10, q14 2754.else 2755 vsub.i16 q4, q4, q14 2756 vsub.i16 q5, q5, q14 2757 vsub.i16 q9, q9, q14 2758 vsub.i16 q10, q10, q14 2759.endif 2760 vst1.16 {q4, q5}, [\dst, :128]! 2761 vst1.16 {q9, q10}, [\ds2, :128]! 2762 ble 9f 2763 2764 vmov q4, q6 2765 vmov q9, q11 2766 b 16b 2767 27689: 2769 add \dst, \dst, \d_strd 2770 add \ds2, \ds2, \d_strd 2771 add \src, \src, \s_strd 2772 add \sr2, \sr2, \s_strd 2773 2774 subs \h, \h, #2 2775 bgt 161b 2776 vpop {q4-q7} 2777 pop {r4-r11,pc} 2778 2779 2780L(\type\()_bilin_v): 2781 cmp \h, #4 2782 adr r10, L(\type\()_bilin_v_tbl) 2783.ifc \type, prep 2784 vdup.16 q15, r11 // 4 - intermediate_bits 2785.endif 2786 ldr r9, [r10, r9, lsl #2] 2787.ifc \type, prep 2788 vmov.i16 q14, #PREP_BIAS 2789 vneg.s16 q15, q15 // -(4-intermediate_bits) 2790.endif 2791 add r10, r10, r9 2792 bx r10 2793 2794 .align 2 2795L(\type\()_bilin_v_tbl): 2796 .word 1280f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2797 .word 640f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2798 .word 320f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2799 .word 160f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2800 .word 80f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2801 .word 40f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2802 .word 20f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2803 280420: // 2xN v 2805.ifc \type, put 2806 cmp \h, #2 2807 add \ds2, \dst, \d_strd 2808 add \sr2, \src, \s_strd 2809 lsl \s_strd, \s_strd, #1 2810 lsl \d_strd, \d_strd, #1 2811 2812 // 2x2 v 2813 vld1.32 {d16[]}, [\src], \s_strd 2814 bgt 24f 281522: 2816 vld1.32 {d17[]}, [\sr2], \s_strd 2817 vld1.32 {d18[]}, [\src], \s_strd 2818 vext.8 d16, d16, d17, #4 2819 vext.8 d17, d17, d18, #4 2820 vmul.i16 d16, d16, d4 2821 vmla.i16 d16, d17, d6 2822 vrshr.u16 d16, d16, #4 2823 vst1.32 {d16[0]}, [\dst, :32] 2824 vst1.32 {d16[1]}, [\ds2, :32] 2825 pop {r4-r11,pc} 282624: // 2x4, 2x6, 2x8, ... v 2827 vld1.32 {d17[]}, [\sr2], \s_strd 2828 vld1.32 {d18[]}, [\src], \s_strd 2829 vld1.32 {d19[]}, [\sr2], \s_strd 2830 vld1.32 {d20[]}, [\src], \s_strd 2831 subs \h, \h, #4 2832 vext.8 d16, d16, d17, #4 2833 vext.8 d17, d17, d18, #4 2834 vext.8 d18, d18, d19, #4 2835 vext.8 d19, d19, d20, #4 2836 vswp d17, d18 2837 vmul.i16 q8, q8, q2 2838 vmla.i16 q8, q9, q3 2839 cmp \h, #2 2840 vrshr.u16 q8, q8, #4 2841 vst1.32 {d16[0]}, [\dst, :32], \d_strd 2842 vst1.32 {d16[1]}, [\ds2, :32], \d_strd 2843 vst1.32 {d17[0]}, [\dst, :32], \d_strd 2844 vst1.32 {d17[1]}, [\ds2, :32], \d_strd 2845 blt 0f 2846 vmov d16, d20 2847 beq 22b 2848 b 24b 28490: 2850 pop {r4-r11,pc} 2851.endif 2852 285340: // 4xN v 2854 add \ds2, \dst, \d_strd 2855 add \sr2, \src, \s_strd 2856 lsl \s_strd, \s_strd, #1 2857 lsl \d_strd, \d_strd, #1 2858 vld1.16 {d16}, [\src], \s_strd 28594: 2860 vld1.16 {d17}, [\sr2], \s_strd 2861 vld1.16 {d19}, [\src], \s_strd 2862 vmov d18, d17 2863 vmul.i16 q8, q8, q2 2864 vmla.i16 q8, q9, q3 2865 subs \h, \h, #2 2866.ifc \type, put 2867 vrshr.u16 q8, q8, #4 2868.else 2869 vrshl.u16 q8, q8, q15 2870 vsub.i16 q8, q8, q14 2871.endif 2872 vst1.16 {d16}, [\dst, :64], \d_strd 2873 vst1.16 {d17}, [\ds2, :64], \d_strd 2874 ble 0f 2875 vmov d16, d19 2876 b 4b 28770: 2878 pop {r4-r11,pc} 2879 288080: // 8xN v 2881 add \ds2, \dst, \d_strd 2882 add \sr2, \src, \s_strd 2883 lsl \s_strd, \s_strd, #1 2884 lsl \d_strd, \d_strd, #1 2885 vld1.16 {q8}, [\src], \s_strd 28868: 2887 vld1.16 {q9}, [\sr2], \s_strd 2888 vld1.16 {q10}, [\src], \s_strd 2889 vmul.i16 q8, q8, q2 2890 vmla.i16 q8, q9, q3 2891 vmul.i16 q9, q9, q2 2892 vmla.i16 q9, q10, q3 2893 subs \h, \h, #2 2894.ifc \type, put 2895 vrshr.u16 q8, q8, #4 2896 vrshr.u16 q9, q9, #4 2897.else 2898 vrshl.u16 q8, q8, q15 2899 vrshl.u16 q9, q9, q15 2900 vsub.i16 q8, q8, q14 2901 vsub.i16 q9, q9, q14 2902.endif 2903 vst1.16 {q8}, [\dst, :128], \d_strd 2904 vst1.16 {q9}, [\ds2, :128], \d_strd 2905 ble 0f 2906 vmov q8, q10 2907 b 8b 29080: 2909 pop {r4-r11,pc} 2910 2911160: // 16xN, 32xN, ... 2912320: 2913640: 29141280: 2915 mov \my, \h 29161: 2917 add \ds2, \dst, \d_strd 2918 add \sr2, \src, \s_strd 2919 lsl \s_strd, \s_strd, #1 2920 lsl \d_strd, \d_strd, #1 2921 2922 vld1.16 {q8, q9}, [\src], \s_strd 29232: 2924 vld1.16 {q10, q11}, [\sr2], \s_strd 2925 vld1.16 {q12, q13}, [\src], \s_strd 2926 vmul.i16 q8, q8, q2 2927 vmla.i16 q8, q10, q3 2928 vmul.i16 q9, q9, q2 2929 vmla.i16 q9, q11, q3 2930 vmul.i16 q10, q10, q2 2931 vmla.i16 q10, q12, q3 2932 vmul.i16 q11, q11, q2 2933 vmla.i16 q11, q13, q3 2934 subs \h, \h, #2 2935.ifc \type, put 2936 vrshr.u16 q8, q8, #4 2937 vrshr.u16 q9, q9, #4 2938 vrshr.u16 q10, q10, #4 2939 vrshr.u16 q11, q11, #4 2940.else 2941 vrshl.u16 q8, q8, q15 2942 vrshl.u16 q9, q9, q15 2943 vrshl.u16 q10, q10, q15 2944 vrshl.u16 q11, q11, q15 2945 vsub.i16 q8, q8, q14 2946 vsub.i16 q9, q9, q14 2947 vsub.i16 q10, q10, q14 2948 vsub.i16 q11, q11, q14 2949.endif 2950 vst1.16 {q8, q9}, [\dst, :128], \d_strd 2951 vst1.16 {q10, q11}, [\ds2, :128], \d_strd 2952 ble 9f 2953 vmov q8, q12 2954 vmov q9, q13 2955 b 2b 29569: 2957 subs \w, \w, #16 2958 ble 0f 2959 asr \s_strd, \s_strd, #1 2960 asr \d_strd, \d_strd, #1 2961 mls \src, \s_strd, \my, \src 2962 mls \dst, \d_strd, \my, \dst 2963 sub \src, \src, \s_strd, lsl #1 2964 mov \h, \my 2965 add \src, \src, #32 2966 add \dst, \dst, #32 2967 b 1b 29680: 2969 pop {r4-r11,pc} 2970 2971L(\type\()_bilin_hv): 2972 adr r10, L(\type\()_bilin_hv_tbl) 2973 vdup.16 q15, r11 // 4 - intermediate_bits 2974 ldr r9, [r10, r9, lsl #2] 2975 vneg.s16 q15, q15 // -(4-intermediate_bits) 2976.ifc \type, put 2977 vdup.32 q14, r12 // 4 + intermediate_bits 2978.else 2979 vmov.i16 q14, #PREP_BIAS 2980.endif 2981 add r10, r10, r9 2982.ifc \type, put 2983 vneg.s32 q14, q14 // -(4+intermediate_bits) 2984.endif 2985 bx r10 2986 2987 .align 2 2988L(\type\()_bilin_hv_tbl): 2989 .word 1280f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2990 .word 640f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2991 .word 320f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2992 .word 160f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2993 .word 80f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2994 .word 40f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2995 .word 20f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2996 299720: // 2xN hv 2998.ifc \type, put 2999 add \sr2, \src, \s_strd 3000 add \ds2, \dst, \d_strd 3001 lsl \s_strd, \s_strd, #1 3002 lsl \d_strd, \d_strd, #1 3003 3004 vld1.16 {d20}, [\src], \s_strd 3005 vext.8 d21, d20, d20, #2 3006 vmul.i16 d16, d20, d0 3007 vmla.i16 d16, d21, d2 3008 vrshl.u16 d16, d16, d30 3009 vext.8 d16, d16, d16, #4 3010 30112: 3012 vld1.16 {d20}, [\sr2], \s_strd 3013 vld1.16 {d22}, [\src], \s_strd 3014 vext.8 d21, d20, d20, #2 3015 vext.8 d23, d22, d22, #2 3016 vtrn.32 d20, d22 3017 vtrn.32 d21, d23 3018 vmul.i16 d18, d20, d0 3019 vmla.i16 d18, d21, d2 3020 vrshl.u16 d18, d18, d30 3021 3022 vext.8 d16, d16, d18, #4 3023 3024 vmull.u16 q8, d16, d4 3025 vmlal.u16 q8, d18, d6 3026 vrshl.u32 q8, q8, q14 3027 vmovn.i32 d16, q8 3028 subs \h, \h, #2 3029 vst1.32 {d16[0]}, [\dst, :32], \d_strd 3030 vst1.32 {d16[1]}, [\ds2, :32], \d_strd 3031 ble 0f 3032 vmov d16, d18 3033 b 2b 30340: 3035 pop {r4-r11,pc} 3036.endif 3037 303840: // 4xN hv 3039 add \sr2, \src, \s_strd 3040 add \ds2, \dst, \d_strd 3041 lsl \s_strd, \s_strd, #1 3042 lsl \d_strd, \d_strd, #1 3043 3044 vld1.16 {q10}, [\src], \s_strd 3045 vext.8 d21, d20, d21, #2 3046 vmul.i16 d16, d20, d0 3047 vmla.i16 d16, d21, d2 3048 vrshl.u16 d16, d16, d30 3049 30504: 3051 vld1.16 {q10}, [\sr2], \s_strd 3052 vld1.16 {q11}, [\src], \s_strd 3053 vext.8 d21, d20, d21, #2 3054 vext.8 d23, d22, d23, #2 3055 vswp d21, d22 3056 vmul.i16 q9, q10, q0 3057 vmla.i16 q9, q11, q1 3058 vrshl.u16 q9, q9, q15 3059 3060 vmull.u16 q10, d16, d4 3061 vmlal.u16 q10, d18, d6 3062 vmull.u16 q11, d18, d4 3063 vmlal.u16 q11, d19, d6 3064.ifc \type, put 3065 vrshl.u32 q10, q10, q14 3066 vrshl.u32 q11, q11, q14 3067 vmovn.i32 d20, q10 3068 vmovn.i32 d21, q11 3069.else 3070 vrshrn.i32 d20, q10, #4 3071 vrshrn.i32 d21, q11, #4 3072 vsub.i16 q10, q10, q14 3073.endif 3074 subs \h, \h, #2 3075 vst1.16 {d20}, [\dst, :64], \d_strd 3076 vst1.16 {d21}, [\ds2, :64], \d_strd 3077 ble 0f 3078 vmov d16, d19 3079 b 4b 30800: 3081 pop {r4-r11,pc} 3082 308380: // 8xN, 16xN, ... hv 3084160: 3085320: 3086640: 30871280: 3088 mov \my, \h 3089 30901: 3091 add \sr2, \src, \s_strd 3092 add \ds2, \dst, \d_strd 3093 lsl \s_strd, \s_strd, #1 3094 lsl \d_strd, \d_strd, #1 3095 3096 vld1.16 {d20, d21, d22}, [\src], \s_strd 3097 vext.8 q11, q10, q11, #2 3098 vmul.i16 q8, q10, q0 3099 vmla.i16 q8, q11, q1 3100 vrshl.u16 q8, q8, q15 3101 31022: 3103 vld1.16 {d20, d21, d22}, [\sr2], \s_strd 3104 vld1.16 {d24, d25, d26}, [\src], \s_strd 3105 vext.8 q11, q10, q11, #2 3106 vext.8 q13, q12, q13, #2 3107 vmul.i16 q9, q10, q0 3108 vmla.i16 q9, q11, q1 3109 vmul.i16 q10, q12, q0 3110 vmla.i16 q10, q13, q1 3111 vrshl.u16 q9, q9, q15 3112 vrshl.u16 q10, q10, q15 3113 3114 vmull.u16 q11, d16, d4 3115 vmlal.u16 q11, d18, d6 3116 vmull.u16 q12, d17, d4 3117 vmlal.u16 q12, d19, d6 3118 vmull.u16 q8, d18, d4 3119 vmlal.u16 q8, d20, d6 3120 vmull.u16 q9, d19, d4 3121 vmlal.u16 q9, d21, d6 3122.ifc \type, put 3123 vrshl.u32 q11, q11, q14 3124 vrshl.u32 q12, q12, q14 3125 vrshl.u32 q8, q8, q14 3126 vrshl.u32 q9, q9, q14 3127 vmovn.i32 d22, q11 3128 vmovn.i32 d23, q12 3129 vmovn.i32 d16, q8 3130 vmovn.i32 d17, q9 3131.else 3132 vrshrn.i32 d22, q11, #4 3133 vrshrn.i32 d23, q12, #4 3134 vrshrn.i32 d16, q8, #4 3135 vrshrn.i32 d17, q9, #4 3136 vsub.i16 q11, q11, q14 3137 vsub.i16 q8, q8, q14 3138.endif 3139 subs \h, \h, #2 3140 vst1.16 {q11}, [\dst, :128], \d_strd 3141 vst1.16 {q8}, [\ds2, :128], \d_strd 3142 ble 9f 3143 vmov q8, q10 3144 b 2b 31459: 3146 subs \w, \w, #8 3147 ble 0f 3148 asr \s_strd, \s_strd, #1 3149 asr \d_strd, \d_strd, #1 3150 mls \src, \s_strd, \my, \src 3151 mls \dst, \d_strd, \my, \dst 3152 sub \src, \src, \s_strd, lsl #1 3153 mov \h, \my 3154 add \src, \src, #16 3155 add \dst, \dst, #16 3156 b 1b 31570: 3158 pop {r4-r11,pc} 3159endfunc 3160.endm 3161 3162filter_fn put, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10 3163filter_fn prep, r0, r8, r1, r2, r3, r4, r5, r6, r7, r9, r10 3164 3165.macro load_filter_ptr src 3166 asr r12, \src, #10 3167 add r12, r11, r12, lsl #3 3168.endm 3169 3170.macro load_filter_coef dst, src, inc 3171 add \src, \src, \inc 3172 vld1.8 {\dst}, [r12, :64] 3173.endm 3174 3175.macro load_filter_row dst, src, inc 3176 load_filter_ptr \src 3177 load_filter_coef \dst, \src, \inc 3178.endm 3179 3180function warp_filter_horz_neon 3181 load_filter_ptr r5 // filter 0 3182 vld1.16 {q6,q7}, [r2], r3 3183 3184 load_filter_coef d0, r5, r7 // filter 0 3185 load_filter_row d2, r5, r7 // filter 1 3186 vmovl.s8 q0, d0 // filter 0 3187 vext.8 q3, q6, q7, #2*1 // filter 1 pixels 3188 vmovl.s8 q1, d2 // filter 1 3189 3190 vmull.s16 q4, d12, d0 // filter 0 output (0-3) 3191 vmull.s16 q5, d13, d1 // filter 0 output (4-7) 3192 3193 load_filter_ptr r5 // filter 2 3194 3195 vmull.s16 q2, d6, d2 // filter 1 output (0-3) 3196 vmull.s16 q3, d7, d3 // filter 1 output (4-7) 3197 3198 load_filter_coef d0, r5, r7 // filter 2 3199 3200 vpadd.i32 d8, d8, d9 // half pixel 0 (2x32) 3201 vpadd.i32 d9, d10, d11 // half pixel 0 (2x32) 3202 3203 load_filter_ptr r5 // filter 3 3204 3205 vpadd.i32 d4, d4, d5 // half pixel 1 (2x32) 3206 vpadd.i32 d5, d6, d7 // half pixel 1 (2x32) 3207 3208 vmovl.s8 q0, d0 // filter 2 3209 vext.8 q3, q6, q7, #2*2 // filter 2 pixels 3210 3211 vpadd.i32 d8, d8, d9 // pixel 0 (2x32) 3212 vpadd.i32 d9, d4, d5 // pixel 1 (2x32) 3213 3214 load_filter_coef d2, r5, r7 // filter 3 3215 3216 vmull.s16 q2, d6, d0 // filter 2 output (0-3) 3217 vmull.s16 q3, d7, d1 // filter 2 output (4-7) 3218 3219 load_filter_ptr r5 // filter 4 3220 3221 vpadd.i32 d8, d8, d9 // pixel 0,1 3222 3223 vpadd.i32 d9, d4, d5 // half pixel 2 (2x32) 3224 vpadd.i32 d10, d6, d7 // half pixel 2 (2x32) 3225 3226 vmovl.s8 q1, d2 // filter 3 3227 vext.8 q3, q6, q7, #2*3 // filter 3 pixels 3228 3229 load_filter_coef d0, r5, r7 // filter 4 3230 3231 vpadd.i32 d9, d9, d10 // pixel 2 (2x32) 3232 3233 vmull.s16 q2, d6, d2 // filter 3 output (0-3) 3234 vmull.s16 q3, d7, d3 // filter 3 output (4-7) 3235 3236 vmovl.s8 q0, d0 // filter 4 3237 load_filter_ptr r5 // filter 5 3238 3239 vpadd.i32 d10, d4, d5 // half pixel 3 (2x32) 3240 vpadd.i32 d11, d6, d7 // half pixel 3 (2x32) 3241 3242 vext.8 q3, q6, q7, #2*4 // filter 4 pixels 3243 load_filter_coef d2, r5, r7 // filter 5 3244 3245 vpadd.i32 d10, d10, d11 // pixel 3 (2x32) 3246 3247 vpadd.i32 d9, d9, d10 // pixel 2,3 3248 3249 vmull.s16 q2, d6, d0 // filter 4 output (0-3) 3250 vmull.s16 q3, d7, d1 // filter 4 output (4-7) 3251 3252 vmovl.s8 q1, d2 // filter 5 3253 load_filter_ptr r5 // filter 6 3254 3255 vpadd.i32 d10, d4, d5 // half pixel 4 (2x32) 3256 vpadd.i32 d11, d6, d7 // half pixel 4 (2x32) 3257 3258 vext.8 q3, q6, q7, #2*5 // filter 5 pixels 3259 load_filter_coef d0, r5, r7 // filter 6 3260 3261 vpadd.i32 d10, d10, d11 // pixel 4 (2x32) 3262 3263 vmull.s16 q2, d6, d2 // filter 5 output (0-3) 3264 vmull.s16 q3, d7, d3 // filter 5 output (4-7) 3265 3266 vmovl.s8 q0, d0 // filter 6 3267 load_filter_ptr r5 // filter 7 3268 3269 vpadd.i32 d4, d4, d5 // half pixel 5 (2x32) 3270 vpadd.i32 d5, d6, d7 // half pixel 5 (2x32) 3271 3272 vext.8 q3, q6, q7, #2*6 // filter 6 pixels 3273 load_filter_coef d2, r5, r7 // filter 7 3274 3275 vpadd.i32 d11, d4, d5 // pixel 5 (2x32) 3276 3277 vmull.s16 q2, d6, d0 // filter 6 output (0-3) 3278 vmull.s16 q3, d7, d1 // filter 6 output (4-7) 3279 3280 vmovl.s8 q1, d2 // filter 7 3281 3282 vpadd.i32 d10, d10, d11 // pixel 4,5 3283 3284 vpadd.i32 d4, d4, d5 // half pixel 6 (2x32) 3285 vpadd.i32 d5, d6, d7 // half pixel 6 (2x32) 3286 3287 vext.8 q3, q6, q7, #2*7 // filter 7 pixels 3288 3289 vpadd.i32 d11, d4, d5 // pixel 6 (2x32) 3290 3291 vmull.s16 q2, d6, d2 // filter 7 output (0-3) 3292 vmull.s16 q3, d7, d3 // filter 7 output (4-7) 3293 3294 vld1.32 {d14[],d15[]}, [sp] // -(7 - intermediate_bits) 3295 3296 vpadd.i32 d4, d4, d5 // half pixel 7 (2x32) 3297 vpadd.i32 d5, d6, d7 // half pixel 7 (2x32) 3298 3299 sub r5, r5, r7, lsl #3 3300 3301 vpadd.i32 d4, d4, d5 // pixel 7 (2x32) 3302 3303 add r5, r5, r8 3304 3305 vpadd.i32 d11, d11, d4 // pixel 6,7 3306 3307 vrshl.s32 q4, q4, q7 // -(7 - intermediate_bits) 3308 vrshl.s32 q5, q5, q7 // -(7 - intermediate_bits) 3309 3310 bx lr 3311endfunc 3312 3313// void dav1d_warp_affine_8x8_16bpc_neon( 3314// pixel *dst, const ptrdiff_t dst_stride, 3315// const pixel *src, const ptrdiff_t src_stride, 3316// const int16_t *const abcd, int mx, int my, 3317// const int bitdepth_max) 3318.macro warp t 3319function warp_affine_8x8\t\()_16bpc_neon, export=1 3320 push {r4-r11,lr} 3321 vpush {q4-q7} 3322 ldrd r4, r5, [sp, #100] 3323 ldrd r6, r7, [sp, #108] 3324 sub sp, sp, #8 3325 3326 clz r7, r7 3327 // intermediate_bits = clz(bitdepth_max) - 18 3328.ifb \t 3329 sub r8, r7, #11 // 7 + intermediate_bits = clz(bitdepth_max) - 18 + 7 3330.endif 3331 sub r7, r7, #25 // -(7 - intermediate_bits) 3332.ifb \t 3333 neg r8, r8 // -(7 + intermediate_bits) 3334.endif 3335 str r7, [sp] // spill -(7 - intermediate_bits) on stack 3336.ifb \t 3337 str r8, [sp, #4] // spill -(7 + intermediate_bits) on stack 3338.endif 3339 3340 ldrd r8, r9, [r4] 3341 sxth r7, r8 3342 asr r8, r8, #16 3343 asr r4, r9, #16 3344 sxth r9, r9 3345 mov r10, #8 3346 sub r2, r2, r3, lsl #1 3347 sub r2, r2, r3 3348 sub r2, r2, #6 3349 movrel r11, X(mc_warp_filter), 64*8 3350.ifnb \t 3351 lsl r1, r1, #1 3352.endif 3353 add r5, r5, #512 3354 add r6, r6, #512 3355 3356 bl warp_filter_horz_neon 3357 vmovn.i32 d16, q4 3358 vmovn.i32 d17, q5 3359 bl warp_filter_horz_neon 3360 vmovn.i32 d18, q4 3361 vmovn.i32 d19, q5 3362 bl warp_filter_horz_neon 3363 vmovn.i32 d20, q4 3364 vmovn.i32 d21, q5 3365 bl warp_filter_horz_neon 3366 vmovn.i32 d22, q4 3367 vmovn.i32 d23, q5 3368 bl warp_filter_horz_neon 3369 vmovn.i32 d24, q4 3370 vmovn.i32 d25, q5 3371 bl warp_filter_horz_neon 3372 vmovn.i32 d26, q4 3373 vmovn.i32 d27, q5 3374 bl warp_filter_horz_neon 3375 vmovn.i32 d28, q4 3376 vmovn.i32 d29, q5 3377 33781: 3379 bl warp_filter_horz_neon 3380 vmovn.i32 d30, q4 3381 vmovn.i32 d31, q5 3382 3383 load_filter_row d8, r6, r9 3384 load_filter_row d9, r6, r9 3385 load_filter_row d10, r6, r9 3386 load_filter_row d11, r6, r9 3387 load_filter_row d12, r6, r9 3388 load_filter_row d13, r6, r9 3389 load_filter_row d14, r6, r9 3390 load_filter_row d15, r6, r9 3391 transpose_8x8b q4, q5, q6, q7, d8, d9, d10, d11, d12, d13, d14, d15 3392 vmovl.s8 q1, d8 3393 vmovl.s8 q2, d9 3394 vmovl.s8 q3, d10 3395 vmovl.s8 q4, d11 3396 vmovl.s8 q5, d12 3397 vmovl.s8 q6, d13 3398 3399 sub r6, r6, r9, lsl #3 3400 3401 // This ordering of vmull/vmlal is highly beneficial for 3402 // Cortex A8/A9/A53 here, but harmful for Cortex A7. 3403 vmull.s16 q0, d16, d2 3404 vmlal.s16 q0, d18, d4 3405 vmlal.s16 q0, d20, d6 3406 vmlal.s16 q0, d22, d8 3407 vmlal.s16 q0, d24, d10 3408 vmlal.s16 q0, d26, d12 3409 vmull.s16 q1, d17, d3 3410 vmlal.s16 q1, d19, d5 3411 vmlal.s16 q1, d21, d7 3412 vmlal.s16 q1, d23, d9 3413 vmlal.s16 q1, d25, d11 3414 vmlal.s16 q1, d27, d13 3415 3416 vmovl.s8 q2, d14 3417 vmovl.s8 q3, d15 3418 3419 vmlal.s16 q0, d28, d4 3420 vmlal.s16 q0, d30, d6 3421 vmlal.s16 q1, d29, d5 3422 vmlal.s16 q1, d31, d7 3423 3424.ifb \t 3425 ldr lr, [sp, #4] // -(7 + intermediate_bits) 3426 ldr r12, [sp, #120] // bitdepth_max 3427 vdup.32 q2, lr // -(7 + intermediate_bits) 3428 vdup.16 q3, r12 // bitdepth_max 3429.endif 3430 3431 vmov q8, q9 3432 vmov q9, q10 3433.ifb \t 3434 vrshl.s32 q0, q0, q2 // -(7 + intermediate_bits) 3435 vrshl.s32 q1, q1, q2 // -(7 + intermediate_bits) 3436.else 3437 vrshrn.s32 d0, q0, #7 3438 vrshrn.s32 d1, q1, #7 3439 vmov.i16 q3, #PREP_BIAS 3440.endif 3441 vmov q10, q11 3442.ifb \t 3443 vqmovun.s32 d0, q0 3444 vqmovun.s32 d1, q1 3445.else 3446 vsub.i16 q0, q0, q3 // PREP_BIAS 3447.endif 3448 vmov q11, q12 3449 vmov q12, q13 3450.ifb \t 3451 vmin.u16 q0, q0, q3 // bitdepth_max 3452.endif 3453 vmov q13, q14 3454 vmov q14, q15 3455 subs r10, r10, #1 3456 vst1.16 {q0}, [r0, :128], r1 3457 3458 add r6, r6, r4 3459 bgt 1b 3460 3461 add sp, sp, #8 3462 vpop {q4-q7} 3463 pop {r4-r11,pc} 3464endfunc 3465.endm 3466 3467warp 3468warp t 3469 3470// void dav1d_emu_edge_16bpc_neon( 3471// const intptr_t bw, const intptr_t bh, 3472// const intptr_t iw, const intptr_t ih, 3473// const intptr_t x, const intptr_t y, 3474// pixel *dst, const ptrdiff_t dst_stride, 3475// const pixel *ref, const ptrdiff_t ref_stride) 3476function emu_edge_16bpc_neon, export=1 3477 push {r4-r11,lr} 3478 ldrd r4, r5, [sp, #36] 3479 ldrd r6, r7, [sp, #44] 3480 ldrd r8, r9, [sp, #52] 3481 3482 // ref += iclip(y, 0, ih - 1) * PXSTRIDE(ref_stride) 3483 // ref += iclip(x, 0, iw - 1) 3484 sub r12, r3, #1 // ih - 1 3485 cmp r5, r3 3486 sub lr, r2, #1 // iw - 1 3487 it lt 3488 movlt r12, r5 // min(y, ih - 1) 3489 cmp r4, r2 3490 bic r12, r12, r12, asr #31 // max(min(y, ih - 1), 0) 3491 it lt 3492 movlt lr, r4 // min(x, iw - 1) 3493 bic lr, lr, lr, asr #31 // max(min(x, iw - 1), 0) 3494 mla r8, r12, r9, r8 // ref += iclip() * stride 3495 add r8, r8, lr, lsl #1 // ref += iclip() 3496 3497 // bottom_ext = iclip(y + bh - ih, 0, bh - 1) 3498 // top_ext = iclip(-y, 0, bh - 1) 3499 add r10, r5, r1 // y + bh 3500 neg r5, r5 // -y 3501 sub r10, r10, r3 // y + bh - ih 3502 sub r12, r1, #1 // bh - 1 3503 cmp r10, r1 3504 bic r5, r5, r5, asr #31 // max(-y, 0) 3505 it ge 3506 movge r10, r12 // min(y + bh - ih, bh-1) 3507 cmp r5, r1 3508 bic r10, r10, r10, asr #31 // max(min(y + bh - ih, bh-1), 0) 3509 it ge 3510 movge r5, r12 // min(max(-y, 0), bh-1) 3511 3512 // right_ext = iclip(x + bw - iw, 0, bw - 1) 3513 // left_ext = iclip(-x, 0, bw - 1) 3514 add r11, r4, r0 // x + bw 3515 neg r4, r4 // -x 3516 sub r11, r11, r2 // x + bw - iw 3517 sub lr, r0, #1 // bw - 1 3518 cmp r11, r0 3519 bic r4, r4, r4, asr #31 // max(-x, 0) 3520 it ge 3521 movge r11, lr // min(x + bw - iw, bw-1) 3522 cmp r4, r0 3523 bic r11, r11, r11, asr #31 // max(min(x + bw - iw, bw-1), 0) 3524 it ge 3525 movge r4, lr // min(max(-x, 0), bw - 1) 3526 3527 // center_h = bh - top_ext - bottom_ext 3528 // dst += top_ext * PXSTRIDE(dst_stride) 3529 // center_w = bw - left_ext - right_ext 3530 sub r1, r1, r5 // bh - top_ext 3531 mla r6, r5, r7, r6 3532 sub r2, r0, r4 // bw - left_ext 3533 sub r1, r1, r10 // center_h = bh - top_ext - bottom_ext 3534 sub r2, r2, r11 // center_w = bw - left_ext - right_ext 3535 3536 mov r0, r6 // backup of dst 3537 3538.macro v_loop need_left, need_right 35390: 3540.if \need_left 3541 vld1.16 {d0[], d1[]}, [r8] 3542 mov r12, r6 // out = dst 3543 mov r3, r4 3544 vmov q1, q0 35451: 3546 subs r3, r3, #16 3547 vst1.16 {q0, q1}, [r12, :128]! 3548 bgt 1b 3549.endif 3550 mov lr, r8 3551 add r12, r6, r4, lsl #1 // out = dst + left_ext 3552 mov r3, r2 35531: 3554 vld1.16 {q0, q1}, [lr]! 3555 subs r3, r3, #32 3556 vld1.16 {q2, q3}, [lr]! 3557.if \need_left 3558 vst1.16 {q0, q1}, [r12]! 3559 vst1.16 {q2, q3}, [r12]! 3560.else 3561 vst1.16 {q0, q1}, [r12, :128]! 3562 vst1.16 {q2, q3}, [r12, :128]! 3563.endif 3564 bgt 1b 3565.if \need_right 3566 add r3, r8, r2, lsl #1 // in + center_w 3567 sub r3, r3, #2 // in + center_w - 1 3568 add r12, r6, r4, lsl #1 // dst + left_ext 3569 vld1.16 {d0[], d1[]}, [r3] 3570 add r12, r12, r2, lsl #1 // out = dst + left_ext + center_w 3571 mov r3, r11 3572 vmov q1, q0 35731: 3574 subs r3, r3, #16 3575 vst1.16 {q0, q1}, [r12]! 3576 bgt 1b 3577.endif 3578 3579 subs r1, r1, #1 // center_h-- 3580 add r6, r6, r7 3581 add r8, r8, r9 3582 bgt 0b 3583.endm 3584 3585 cmp r4, #0 3586 beq 2f 3587 // need_left 3588 cmp r11, #0 3589 beq 3f 3590 // need_left + need_right 3591 v_loop 1, 1 3592 b 5f 3593 35942: 3595 // !need_left 3596 cmp r11, #0 3597 beq 4f 3598 // !need_left + need_right 3599 v_loop 0, 1 3600 b 5f 3601 36023: 3603 // need_left + !need_right 3604 v_loop 1, 0 3605 b 5f 3606 36074: 3608 // !need_left + !need_right 3609 v_loop 0, 0 3610 36115: 3612 cmp r10, #0 3613 // Storing the original dst in r0 overwrote bw, recalculate it here 3614 add r2, r2, r4 // center_w + left_ext 3615 add r2, r2, r11 // bw = center_w + left_ext + right_ext 3616 3617 beq 3f 3618 // need_bottom 3619 sub r8, r6, r7 // ref = dst - stride 3620 mov r4, r2 3621 sub r12, r7, #32 36221: 3623 vld1.16 {q0, q1}, [r8, :128]! 3624 mov r3, r10 3625 vld1.16 {q2, q3}, [r8, :128]! 36262: 3627 vst1.16 {q0, q1}, [r6, :128]! 3628 subs r3, r3, #1 3629 vst1.16 {q2, q3}, [r6, :128], r12 3630 bgt 2b 3631 mls r6, r7, r10, r6 // dst -= bottom_ext * stride 3632 subs r4, r4, #32 // bw -= 32 3633 add r6, r6, #64 // dst += 32 3634 bgt 1b 3635 36363: 3637 cmp r5, #0 3638 beq 3f 3639 // need_top 3640 mls r6, r7, r5, r0 // dst = stored_dst - top_ext * stride 3641 sub r12, r7, #32 36421: 3643 vld1.16 {q0, q1}, [r0, :128]! 3644 mov r3, r5 3645 vld1.16 {q2, q3}, [r0, :128]! 36462: 3647 vst1.16 {q0, q1}, [r6, :128]! 3648 subs r3, r3, #1 3649 vst1.16 {q2, q3}, [r6, :128], r12 3650 bgt 2b 3651 mls r6, r7, r5, r6 // dst -= top_ext * stride 3652 subs r2, r2, #32 // bw -= 32 3653 add r6, r6, #64 // dst += 32 3654 bgt 1b 3655 36563: 3657 pop {r4-r11,pc} 3658endfunc 3659