1/* 2 * Copyright © 2018, VideoLAN and dav1d authors 3 * Copyright © 2018, Janne Grunau 4 * Copyright © 2018, 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.macro avg dst0, dst1, t0, t1, t2, t3 33 vld1.16 {\t0,\t1}, [r2, :128]! 34 vld1.16 {\t2,\t3}, [r3, :128]! 35 vadd.i16 \t0, \t0, \t2 36 vadd.i16 \t1, \t1, \t3 37 vqrshrun.s16 \dst0, \t0, #5 38 vqrshrun.s16 \dst1, \t1, #5 39.endm 40 41.macro w_avg dst0, dst1, t0, t1, t2, t3 42 vld1.16 {\t0,\t1}, [r2, :128]! 43 vld1.16 {\t2,\t3}, [r3, :128]! 44 vsub.i16 \t0, \t2, \t0 45 vsub.i16 \t1, \t3, \t1 46 vqdmulh.s16 \t0, \t0, q15 47 vqdmulh.s16 \t1, \t1, q15 48 vadd.i16 \t0, \t2, \t0 49 vadd.i16 \t1, \t3, \t1 50 vqrshrun.s16 \dst0, \t0, #4 51 vqrshrun.s16 \dst1, \t1, #4 52.endm 53 54.macro mask dst0, dst1, t0, t1, t2, t3 55 vld1.8 {q14}, [lr, :128]! 56 vld1.16 {\t0,\t1}, [r2, :128]! 57 vmul.i8 q14, q14, q15 58 vld1.16 {\t2,\t3}, [r3, :128]! 59 vshll.i8 q13, d28, #8 60 vshll.i8 q14, d29, #8 61 vsub.i16 \t0, \t2, \t0 62 vsub.i16 \t1, \t3, \t1 63 vqdmulh.s16 \t0, \t0, q13 64 vqdmulh.s16 \t1, \t1, q14 65 vadd.i16 \t0, \t2, \t0 66 vadd.i16 \t1, \t3, \t1 67 vqrshrun.s16 \dst0, \t0, #4 68 vqrshrun.s16 \dst1, \t1, #4 69.endm 70 71.macro bidir_fn type 72function \type\()_8bpc_neon, export=1 73 push {r4-r6,lr} 74 ldrd r4, r5, [sp, #16] 75 clz r4, r4 76.ifnc \type, avg 77 ldr lr, [sp, #24] 78.endif 79.ifc \type, w_avg 80 vdup.s16 q15, lr 81 vneg.s16 q15, q15 82 vshl.i16 q15, q15, #11 83.endif 84.ifc \type, mask 85 vmov.i8 q15, #256-2 86.endif 87 adr r12, L(\type\()_tbl) 88 sub r4, r4, #24 89 ldr r4, [r12, r4, lsl #2] 90 \type d16, d17, q0, q1, q2, q3 91 add r12, r12, r4 92 bx r12 93 94 .align 2 95L(\type\()_tbl): 96 .word 1280f - L(\type\()_tbl) + CONFIG_THUMB 97 .word 640f - L(\type\()_tbl) + CONFIG_THUMB 98 .word 320f - L(\type\()_tbl) + CONFIG_THUMB 99 .word 160f - L(\type\()_tbl) + CONFIG_THUMB 100 .word 80f - L(\type\()_tbl) + CONFIG_THUMB 101 .word 4f - L(\type\()_tbl) + CONFIG_THUMB 102 1034: 104 add r6, r0, r1 105 lsl r1, r1, #1 106 cmp r5, #4 107 vst1.32 {d16[0]}, [r0, :32], r1 108 vst1.32 {d16[1]}, [r6, :32], r1 109 vst1.32 {d17[0]}, [r0, :32], r1 110 vst1.32 {d17[1]}, [r6, :32], r1 111 beq 0f 112 \type d18, d19, q0, q1, q2, q3 113 cmp r5, #8 114 vst1.32 {d18[0]}, [r0, :32], r1 115 vst1.32 {d18[1]}, [r6, :32], r1 116 vst1.32 {d19[0]}, [r0, :32], r1 117 vst1.32 {d19[1]}, [r6, :32], r1 118 beq 0f 119 \type d16, d17, q0, q1, q2, q3 120 vst1.32 {d16[0]}, [r0, :32], r1 121 vst1.32 {d16[1]}, [r6, :32], r1 122 \type d18, d19, q0, q1, q2, q3 123 vst1.32 {d17[0]}, [r0, :32], r1 124 vst1.32 {d17[1]}, [r6, :32], r1 125 vst1.32 {d18[0]}, [r0, :32], r1 126 vst1.32 {d18[1]}, [r6, :32], r1 127 vst1.32 {d19[0]}, [r0, :32], r1 128 vst1.32 {d19[1]}, [r6, :32], r1 129 pop {r4-r6,pc} 13080: 131 add r6, r0, r1 132 lsl r1, r1, #1 1338: 134 vst1.8 {d16}, [r0, :64], r1 135 \type d18, d19, q0, q1, q2, q3 136 vst1.8 {d17}, [r6, :64], r1 137 vst1.8 {d18}, [r0, :64], r1 138 subs r5, r5, #4 139 vst1.8 {d19}, [r6, :64], r1 140 ble 0f 141 \type d16, d17, q0, q1, q2, q3 142 b 8b 143160: 144 add r6, r0, r1 145 lsl r1, r1, #1 14616: 147 \type d18, d19, q0, q1, q2, q3 148 vst1.8 {q8}, [r0, :128], r1 149 \type d20, d21, q0, q1, q2, q3 150 vst1.8 {q9}, [r6, :128], r1 151 \type d22, d23, q0, q1, q2, q3 152 vst1.8 {q10}, [r0, :128], r1 153 subs r5, r5, #4 154 vst1.8 {q11}, [r6, :128], r1 155 ble 0f 156 \type d16, d17, q0, q1, q2, q3 157 b 16b 158320: 159 add r6, r0, r1 160 lsl r1, r1, #1 16132: 162 \type d18, d19, q0, q1, q2, q3 163 \type d20, d21, q0, q1, q2, q3 164 vst1.8 {q8, q9}, [r0, :128], r1 165 \type d22, d23, q0, q1, q2, q3 166 subs r5, r5, #2 167 vst1.8 {q10, q11}, [r6, :128], r1 168 ble 0f 169 \type d16, d17, q0, q1, q2, q3 170 b 32b 171640: 172 add r6, r0, #32 17364: 174 \type d18, d19, q0, q1, q2, q3 175 \type d20, d21, q0, q1, q2, q3 176 \type d22, d23, q0, q1, q2, q3 177 vst1.8 {q8, q9}, [r0, :128], r1 178 \type d16, d17, q0, q1, q2, q3 179 vst1.8 {q10, q11}, [r6, :128], r1 180 \type d18, d19, q0, q1, q2, q3 181 \type d20, d21, q0, q1, q2, q3 182 vst1.8 {q8, q9}, [r0, :128], r1 183 \type d22, d23, q0, q1, q2, q3 184 subs r5, r5, #2 185 vst1.8 {q10, q11}, [r6, :128], r1 186 ble 0f 187 \type d16, d17, q0, q1, q2, q3 188 b 64b 1891280: 190 sub r1, r1, #32 191 add r6, r0, #64 192128: 193 \type d18, d19, q0, q1, q2, q3 194 \type d20, d21, q0, q1, q2, q3 195 \type d22, d23, q0, q1, q2, q3 196 vst1.8 {q8, q9}, [r0, :128]! 197 \type d16, d17, q0, q1, q2, q3 198 vst1.8 {q10, q11}, [r0, :128], r1 199 \type d18, d19, q0, q1, q2, q3 200 \type d20, d21, q0, q1, q2, q3 201 vst1.8 {q8, q9}, [r6, :128]! 202 \type d22, d23, q0, q1, q2, q3 203 subs r5, r5, #1 204 vst1.8 {q10, q11}, [r6, :128], r1 205 ble 0f 206 \type d16, d17, q0, q1, q2, q3 207 b 128b 208 2090: 210 pop {r4-r6,pc} 211endfunc 212.endm 213 214bidir_fn avg 215bidir_fn w_avg 216bidir_fn mask 217 218 219.macro w_mask_fn type 220function w_mask_\type\()_8bpc_neon, export=1 221 push {r4-r9,lr} 222 ldrd r4, r5, [sp, #28] 223 ldrd r6, r7, [sp, #36] 224 clz r8, r4 225 adr r9, L(w_mask_\type\()_tbl) 226 sub r8, r8, #24 227 ldr r8, [r9, r8, lsl #2] 228 add r9, r9, r8 229 movw r12, #6903 230 vdup.16 q14, r12 231.if \type == 444 232 vmov.i8 q15, #64 233.elseif \type == 422 234 vdup.8 d0, r7 // d0[] <- sign 235 vmov.i8 d30, #129 236 vsub.i8 d30, d30, d0 // 129 - sign 237.elseif \type == 420 238 vdup.16 q0, r7 // d0[] <- sign 239 vmov.i16 q15, #256 240 vsub.i16 q15, q15, q0 // 256 - sign 241.endif 242 add r12, r0, r1 243 lsl r1, r1, #1 244 bx r9 245 246 .align 2 247L(w_mask_\type\()_tbl): 248 .word 1280f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 249 .word 640f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 250 .word 320f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 251 .word 160f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 252 .word 8f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 253 .word 4f - L(w_mask_\type\()_tbl) + CONFIG_THUMB 254 2554: 256 vld1.16 {d0, d1, d2, d3}, [r2, :128]! // tmp1 (four rows at once) 257 vld1.16 {d4, d5, d6, d7}, [r3, :128]! // tmp2 (four rows at once) 258 subs r5, r5, #4 259 vsub.i16 q8, q2, q0 // tmp2-tmp1 260 vsub.i16 q9, q3, q1 261 vabd.s16 q10, q0, q2 // (abs(tmp1[x] - tmp2[x])) 262 vabd.s16 q11, q1, q3 263 vqsub.u16 q10, q14, q10 // 6903 - abs () 264 vqsub.u16 q11, q14, q11 265 vshr.s16 q10, q10, #8 // 64-m = (6903 - abs()) >> 8 266 vshr.s16 q11, q11, #8 267 vshl.s16 q12, q10, #9 // (64-m)<<9 268 vshl.s16 q13, q11, #9 269 vqdmulh.s16 q12, q12, q8 // ((tmp2-tmp1)*(64-m)<<9)>>15 270 vqdmulh.s16 q13, q13, q9 271 vadd.i16 q12, q12, q0 // (((tmp2-tmp1)*(64-m)<<9)>>15) + tmp1 272 vadd.i16 q13, q13, q1 273 vqrshrun.s16 d24, q12, #4 // (((((tmp2-tmp1)*(64-m)<<9)>>15) + tmp1) + 8) >> 4 274 vqrshrun.s16 d25, q13, #4 275.if \type == 444 276 vmovn.u16 d20, q10 // 64 - m 277 vmovn.u16 d21, q11 278 vsub.i8 q10, q15, q10 // m 279 vst1.8 {d20, d21}, [r6, :128]! 280.elseif \type == 422 281 vpadd.s16 d20, d20, d21 // (64 - m) + (64 - n) (column wise addition) 282 vpadd.s16 d21, d22, d23 283 vmovn.s16 d6, q10 284 vhsub.u8 d6, d30, d6 // ((129 - sign) - ((64 - m) + (64 - n))) >> 1 285 vst1.8 {d6}, [r6, :64]! 286.elseif \type == 420 287 vadd.s16 d20, d20, d21 // (64 - my1) + (64 - my2) (row wise addition) 288 vadd.s16 d21, d22, d23 289 vpadd.s16 d20, d20, d21 // (128 - m) + (128 - n) (column wise addition) 290 vsub.s16 d20, d30, d20 // (256 - sign) - ((128 - m) + (128 - n)) 291 vrshrn.u16 d20, q10, #2 // ((256 - sign) - ((128 - m) + (128 - n)) + 2) >> 2 292 vst1.32 {d20[0]}, [r6, :32]! 293.endif 294 vst1.32 {d24[0]}, [r0, :32], r1 295 vst1.32 {d24[1]}, [r12, :32], r1 296 vst1.32 {d25[0]}, [r0, :32], r1 297 vst1.32 {d25[1]}, [r12, :32], r1 298 bgt 4b 299 pop {r4-r9,pc} 3008: 301 vld1.16 {d0, d1, d2, d3}, [r2, :128]! // tmp1y1, tmp1y2 302 vld1.16 {d4, d5, d6, d7}, [r3, :128]! // tmp2y1, tmp2y2 303 subs r5, r5, #2 304 vsub.i16 q8, q2, q0 // tmp2y1 - tmp1y1 305 vsub.i16 q9, q3, q1 // tmp2y2 - tmp1y2 306 vabd.s16 q10, q0, q2 // abs(tmp1y1 - tmp2y1) 307 vabd.s16 q11, q1, q3 // abs(tmp1y2 - tmp2y2) 308 vqsub.u16 q10, q14, q10 // 6903 - abs(tmp1y1 - tmp2y1) 309 vqsub.u16 q11, q14, q11 // 6903 - abs(tmp1y2 - tmp2y2) 310 vshr.s16 q10, q10, #8 // 64 - my1 = 6903 - abs(tmp1y1 - tmp2y1) >> 8 311 vshr.s16 q11, q11, #8 // 64 - my2 = 6903 - abs(tmp1y2 - tmp2y2) >> 8 312 vshl.s16 q12, q10, #9 // (64 - my1) << 9 313 vshl.s16 q13, q11, #9 // (64 - my2) << 9 314 vqdmulh.s16 q12, q12, q8 // ((tmp2y1 - tmp1y1) * (64 - my1) << 9) >> 15 315 vqdmulh.s16 q13, q13, q9 // ((tmp2y2 - tmp1y2) * (64 - my2) << 9) >> 15 316 vadd.s16 q12, q12, q0 // (((tmp2y1 - tmp1y1) * (64 - my1) << 9) >> 15) + tmp1y1 317 vadd.s16 q13, q13, q1 // (((tmp2y2 - tmp1y2) * (64 - my2) << 9) >> 15) + tmp1y2 318 vqrshrun.s16 d24, q12, #4 // (((((tmp2y1 - tmp1y1) * (64 - my1) << 9) >> 15) + tmp1y1) + 8) >> 4 319 vqrshrun.s16 d25, q13, #4 // (((((tmp2y2 - tmp1y2) * (64 - my2) << 9) >> 15) + tmp1y2) + 8) >> 4 320.if \type == 444 321 vmovn.u16 d20, q10 // 64 - m 322 vmovn.u16 d21, q11 323 vsub.i8 q10, q15, q10 // m 324 vst1.8 {d20, d21}, [r6, :128]! 325.elseif \type == 422 326 vpadd.s16 d20, d20, d21 // (64 - my1) + (64 - ny1) (column wise addition) 327 vpadd.s16 d21, d22, d23 // (64 - my2) + (64 - ny2) 328 vmovn.s16 d20, q10 329 vhsub.u8 d20, d30, d20 // ((129 - sign) - ((64 - my1/y2) + (64 - ny1/y2))) >> 1 330 vst1.8 {d20}, [r6, :64]! 331.elseif \type == 420 332 vadd.s16 q10, q10, q11 // (64 - my1) + (64 - my2) (row wise addition) 333 vpadd.s16 d20, d20, d21 // (128 - m) + (128 - n) (column wise addition) 334 vsub.s16 d20, d30, d20 // (256 - sign) - ((128 - m) + (128 - n)) 335 vrshrn.u16 d20, q10, #2 // ((256 - sign) - ((128 - m) + (128 - n)) + 2) >> 2 336 vst1.32 {d20[0]}, [r6, :32]! 337.endif 338 vst1.16 {d24}, [r0, :64], r1 339 vst1.16 {d25}, [r12, :64], r1 340 bgt 8b 341 pop {r4-r9,pc} 3421280: 343640: 344320: 345160: 346 sub r1, r1, r4 347.if \type == 444 348 add lr, r6, r4 349.elseif \type == 422 350 add lr, r6, r4, lsr #1 351.endif 352 add r9, r3, r4, lsl #1 353 add r7, r2, r4, lsl #1 354161: 355 mov r8, r4 35616: 357 vld1.16 {d0, d1, d2, d3}, [r2, :128]! // tmp1y1 358 vld1.16 {d4, d5, d6, d7}, [r3, :128]! // tmp2y1 359 vld1.16 {d16, d17, d18, d19}, [r7, :128]! // tmp1y2 360 subs r8, r8, #16 361 vsub.i16 q2, q2, q0 // tmp2y1 - tmp1y1 362 vsub.i16 q3, q3, q1 363 vabs.s16 q10, q2 // abs(tm2y1 - tmp1y1) 364 vabs.s16 q11, q3 365 vqsub.u16 q10, q14, q10 // 6903 - abs(tmp1y1 - tmp2y1) 366 vqsub.u16 q11, q14, q11 367 vshr.s16 q10, q10, #8 // 64 - my1 = 6903 - abs(tmp1y1 - tmp2y1) >> 8 368 vshr.s16 q11, q11, #8 369 vshl.s16 q12, q10, #9 // (64 - my1) << 9 370 vshl.s16 q13, q11, #9 371 vqdmulh.s16 q12, q12, q2 // ((tmp2y1 - tmp1y1) * (64 - my1) << 9) >> 15 372 vqdmulh.s16 q13, q13, q3 373 vadd.i16 q12, q12, q0 // (((tmp2y1 - tmp1y1) * (64 - my1) << 9) >> 15) + tmp1y1 374 vadd.i16 q13, q13, q1 375 vld1.16 {d0, d1, d2, d3}, [r9, :128]! // tmp2h2 376.if \type == 444 377 vmovn.u16 d20, q10 // 64 - my1 378 vmovn.u16 d21, q11 379 vsub.i8 q10, q15, q10 // my1 380 vst1.8 {d20, d21}, [r6, :128]! 381.elseif \type == 422 382 vpadd.s16 d20, d20, d21 // (64 - my1) + (64 - ny1) (column wise addition) 383 vpadd.s16 d21, d22, d23 384 vmovn.s16 d20, q10 385 vhsub.u8 d20, d30, d20 // ((129 - sign) - ((64 - my1) + (64 - ny1))) >> 1 386 vst1.8 {d20}, [r6, :64]! 387.endif 388 vqrshrun.s16 d24, q12, #4 // (((((tmp2y1 - tmp1y1)*(64 - my1) << 9) >> 15) + tmp1y1) + 8) >> 4 389 vqrshrun.s16 d25, q13, #4 390 vsub.i16 q0, q0, q8 // tmp2y2 - tmp1y2 391 vsub.i16 q1, q1, q9 392 vst1.16 {d24, d25}, [r0, :128]! // store dsty1 393 vabs.s16 q2, q0 // abs(tmp2y2 - tmp1y2) 394 vabs.s16 q3, q1 395 vqsub.u16 q2, q14, q2 // 6903 - abs(tmp2y2 - tmp1y2) 396 vqsub.u16 q3, q14, q3 397 vshr.s16 q2, q2, #8 // (6903 - abs(tmp2y2 - tmp1y2)) >> 8 398 vshr.s16 q3, q3, #8 399 vshl.s16 q12, q2, #9 // (64 - my2) << 9 400 vshl.s16 q13, q3, #9 401.if \type == 444 402 vmovn.u16 d4, q2 // 64 - my2 403 vmovn.u16 d5, q3 404 vsub.i8 q2, q15, q2 // my2 405 vst1.8 {d4, d5}, [lr, :128]! 406.elseif \type == 422 407 vpadd.s16 d4, d4, d5 // (64 - my2) + (64 - ny2) (column wise addition) 408 vpadd.s16 d5, d6, d7 409 vmovn.s16 d4, q2 410 vhsub.u8 d4, d30, d4 // ((129 - sign) - ((64 - my2) + (64 - ny2))) >> 1 411 vst1.8 {d4}, [lr, :64]! 412.elseif \type == 420 413 vadd.s16 q10, q10, q2 // (64 - my1) + (64 - my2) (row wise addition) 414 vadd.s16 q11, q11, q3 415 vpadd.s16 d20, d20, d21 // (128 - m) + (128 - n) (column wise addition) 416 vpadd.s16 d21, d22, d23 417 vsub.s16 q10, q15, q10 // (256 - sign) - ((128 - m) + (128 - n)) 418 vrshrn.u16 d20, q10, #2 // ((256 - sign) - ((128 - m) + (128 - n)) + 2) >> 2 419 vst1.8 {d20}, [r6, :64]! 420.endif 421 vqdmulh.s16 q12, q12, q0 // ((tmp2y2 - tmp1y2) * (64 - my2) << 9) >> 15 422 vqdmulh.s16 q13, q13, q1 423 vadd.i16 q12, q12, q8 // (((tmp2y2 - tmp1y2) * (64 - my2) << 9) >> 15) + tmp1y2 424 vadd.i16 q13, q13, q9 425 vqrshrun.s16 d24, q12, #4 // (((((tmp2y2 - tmp1y2)*(64 - my2) << 9) >> 15) + tmp1y2) + 8) >> 4 426 vqrshrun.s16 d25, q13, #4 427 vst1.16 {d24, d25}, [r12, :128]! // store dsty2 428 bgt 16b 429 subs r5, r5, #2 430 add r2, r2, r4, lsl #1 431 add r3, r3, r4, lsl #1 432 add r7, r7, r4, lsl #1 433 add r9, r9, r4, lsl #1 434.if \type == 444 435 add r6, r6, r4 436 add lr, lr, r4 437.elseif \type == 422 438 add r6, r6, r4, lsr #1 439 add lr, lr, r4, lsr #1 440.endif 441 add r0, r0, r1 442 add r12, r12, r1 443 bgt 161b 444 pop {r4-r9,pc} 445endfunc 446.endm 447 448w_mask_fn 444 449w_mask_fn 422 450w_mask_fn 420 451 452 453function blend_8bpc_neon, export=1 454 push {r4-r5,lr} 455 ldrd r4, r5, [sp, #12] 456 clz lr, r3 457 adr r3, L(blend_tbl) 458 sub lr, lr, #26 459 ldr lr, [r3, lr, lsl #2] 460 add r3, r3, lr 461 bx r3 462 463 .align 2 464L(blend_tbl): 465 .word 320f - L(blend_tbl) + CONFIG_THUMB 466 .word 160f - L(blend_tbl) + CONFIG_THUMB 467 .word 80f - L(blend_tbl) + CONFIG_THUMB 468 .word 40f - L(blend_tbl) + CONFIG_THUMB 469 47040: 471 vmov.i8 d22, #64 472 add r12, r0, r1 473 lsl r1, r1, #1 4744: 475 vld1.u8 {d2}, [r5, :64]! 476 vld1.u8 {d1}, [r2, :64]! 477 vld1.32 {d0[]}, [r0, :32] 478 subs r4, r4, #2 479 vld1.32 {d0[1]}, [r12, :32] 480 vsub.i8 d3, d22, d2 481 vmull.u8 q8, d1, d2 482 vmlal.u8 q8, d0, d3 483 vrshrn.i16 d20, q8, #6 484 vst1.32 {d20[0]}, [r0, :32], r1 485 vst1.32 {d20[1]}, [r12, :32], r1 486 bgt 4b 487 pop {r4-r5,pc} 48880: 489 vmov.i8 d16, #64 490 add r12, r0, r1 491 lsl r1, r1, #1 4928: 493 vld1.u8 {q1}, [r5, :128]! 494 vld1.u8 {q2}, [r2, :128]! 495 vld1.u8 {d0}, [r0, :64] 496 vsub.i8 d17, d16, d2 497 vld1.u8 {d1}, [r12, :64] 498 subs r4, r4, #2 499 vsub.i8 d18, d16, d3 500 vmull.u8 q3, d2, d4 501 vmlal.u8 q3, d0, d17 502 vmull.u8 q10, d3, d5 503 vmlal.u8 q10, d1, d18 504 vrshrn.i16 d22, q3, #6 505 vrshrn.i16 d23, q10, #6 506 vst1.u8 {d22}, [r0, :64], r1 507 vst1.u8 {d23}, [r12, :64], r1 508 bgt 8b 509 pop {r4-r5,pc} 510160: 511 vmov.i8 q12, #64 512 add r12, r0, r1 513 lsl r1, r1, #1 51416: 515 vld1.u8 {q1, q2}, [r5, :128]! 516 vld1.u8 {q8, q9}, [r2, :128]! 517 vld1.u8 {q0}, [r0, :128] 518 subs r4, r4, #2 519 vsub.i8 q15, q12, q1 520 vld1.u8 {q13}, [r12, :128] 521 vmull.u8 q3, d16, d2 522 vmlal.u8 q3, d0, d30 523 vmull.u8 q14, d17, d3 524 vmlal.u8 q14, d1, d31 525 vsub.i8 q15, q12, q2 526 vrshrn.i16 d20, q3, #6 527 vrshrn.i16 d21, q14, #6 528 vmull.u8 q3, d18, d4 529 vmlal.u8 q3, d26, d30 530 vmull.u8 q14, d19, d5 531 vmlal.u8 q14, d27, d31 532 vrshrn.i16 d22, q3, #6 533 vrshrn.i16 d23, q14, #6 534 vst1.u8 {q10}, [r0, :128], r1 535 vst1.u8 {q11}, [r12, :128], r1 536 bgt 16b 537 pop {r4-r5,pc} 538320: 539 vmov.i8 q10, #64 54032: 541 vld1.u8 {q2, q3}, [r5, :128]! 542 vld1.u8 {q8, q9}, [r2, :128]! 543 vld1.u8 {q0, q1}, [r0, :128] 544 subs r4, r4, #1 545 vsub.i8 q11, q10, q2 546 vmull.u8 q15, d16, d4 547 vmlal.u8 q15, d0, d22 548 vmull.u8 q14, d17, d5 549 vmlal.u8 q14, d1, d23 550 vsub.i8 q11, q10, q3 551 vrshrn.i16 d24, q15, #6 552 vrshrn.i16 d25, q14, #6 553 vmull.u8 q15, d18, d6 554 vmlal.u8 q15, d2, d22 555 vmull.u8 q14, d19, d7 556 vmlal.u8 q14, d3, d23 557 vrshrn.i16 d26, q15, #6 558 vrshrn.i16 d27, q14, #6 559 vst1.u8 {q12, q13}, [r0, :128], r1 560 bgt 32b 561 pop {r4-r5,pc} 562endfunc 563 564function blend_h_8bpc_neon, export=1 565 push {r4-r5,lr} 566 ldr r4, [sp, #12] 567 movrel r5, X(obmc_masks) 568 add r5, r5, r4 569 sub r4, r4, r4, lsr #2 570 clz lr, r3 571 adr r12, L(blend_h_tbl) 572 sub lr, lr, #24 573 ldr lr, [r12, lr, lsl #2] 574 add r12, r12, lr 575 bx r12 576 577 .align 2 578L(blend_h_tbl): 579 .word 1280f - L(blend_h_tbl) + CONFIG_THUMB 580 .word 640f - L(blend_h_tbl) + CONFIG_THUMB 581 .word 320f - L(blend_h_tbl) + CONFIG_THUMB 582 .word 160f - L(blend_h_tbl) + CONFIG_THUMB 583 .word 80f - L(blend_h_tbl) + CONFIG_THUMB 584 .word 40f - L(blend_h_tbl) + CONFIG_THUMB 585 .word 20f - L(blend_h_tbl) + CONFIG_THUMB 586 58720: 588 vmov.i8 d22, #64 589 add r12, r0, r1 590 lsl r1, r1, #1 5912: 592 vld1.16 {d2[], d3[]}, [r5, :16]! 593 vld1.32 {d1[]}, [r2, :32]! 594 subs r4, r4, #2 595 vld1.16 {d0[]}, [r0, :16] 596 vzip.8 d2, d3 597 vsub.i8 d4, d22, d2 598 vld1.16 {d0[1]}, [r12, :16] 599 vmull.u8 q8, d1, d2 600 vmlal.u8 q8, d0, d4 601 vrshrn.i16 d20, q8, #6 602 vst1.16 {d20[0]}, [r0, :16], r1 603 vst1.16 {d20[1]}, [r12, :16], r1 604 bgt 2b 605 pop {r4-r5,pc} 60640: 607 vmov.i8 d22, #64 608 add r12, r0, r1 609 lsl r1, r1, #1 6104: 611 vld2.u8 {d2[], d3[]}, [r5, :16]! 612 vld1.u8 {d1}, [r2, :64]! 613 subs r4, r4, #2 614 vext.u8 d2, d2, d3, #4 615 vld1.32 {d0[]}, [r0, :32] 616 vsub.i8 d6, d22, d2 617 vld1.32 {d0[1]}, [r12, :32] 618 vmull.u8 q8, d1, d2 619 vmlal.u8 q8, d0, d6 620 vrshrn.i16 d20, q8, #6 621 vst1.32 {d20[0]}, [r0, :32], r1 622 vst1.32 {d20[1]}, [r12, :32], r1 623 bgt 4b 624 pop {r4-r5,pc} 62580: 626 vmov.i8 q8, #64 627 add r12, r0, r1 628 lsl r1, r1, #1 6298: 630 vld2.u8 {d2[], d3[]}, [r5, :16]! 631 vld1.u8 {d4, d5}, [r2, :128]! 632 vld1.u8 {d0}, [r0, :64] 633 vsub.i8 q9, q8, q1 634 vld1.u8 {d1}, [r12, :64] 635 subs r4, r4, #2 636 vmull.u8 q3, d2, d4 637 vmlal.u8 q3, d0, d18 638 vmull.u8 q10, d3, d5 639 vmlal.u8 q10, d1, d19 640 vrshrn.i16 d22, q3, #6 641 vrshrn.i16 d23, q10, #6 642 vst1.u8 {d22}, [r0, :64], r1 643 vst1.u8 {d23}, [r12, :64], r1 644 bgt 8b 645 pop {r4-r5,pc} 646160: 647 vmov.i8 q12, #64 648 add r12, r0, r1 649 lsl r1, r1, #1 65016: 651 vld2.u8 {d28[], d29[]}, [r5, :16]! 652 vld1.u8 {d2, d3, d4, d5}, [r2, :128]! 653 vsub.i8 q15, q12, q14 654 vld1.u8 {q0}, [r0, :128] 655 subs r4, r4, #2 656 vld1.u8 {q13}, [r12, :128] 657 vmull.u8 q3, d2, d28 658 vmlal.u8 q3, d0, d30 659 vmull.u8 q8, d3, d28 660 vmlal.u8 q8, d1, d30 661 vrshrn.i16 d18, q3, #6 662 vrshrn.i16 d19, q8, #6 663 vmull.u8 q3, d4, d29 664 vmlal.u8 q3, d26, d31 665 vmull.u8 q8, d5, d29 666 vmlal.u8 q8, d27, d31 667 vrshrn.i16 d20, q3, #6 668 vrshrn.i16 d21, q8, #6 669 vst1.u8 {q9}, [r0, :128], r1 670 vst1.u8 {q10}, [r12, :128], r1 671 bgt 16b 672 pop {r4-r5,pc} 673320: 674640: 6751280: 676 vmov.i8 d20, #64 677 sub r1, r1, r3 678321: 679 vld1.u8 {d6[]}, [r5]! 680 vsub.i8 d7, d20, d6 681 mov r12, r3 68232: 683 vld1.u8 {q8, q9}, [r2, :128]! 684 vld1.u8 {q0, q1}, [r0, :128] 685 vmull.u8 q15, d16, d6 686 vmlal.u8 q15, d0, d7 687 vmull.u8 q14, d17, d6 688 vmlal.u8 q14, d1, d7 689 vrshrn.i16 d0, q15, #6 690 vrshrn.i16 d1, q14, #6 691 vmull.u8 q15, d18, d6 692 vmlal.u8 q15, d2, d7 693 vmull.u8 q14, d19, d6 694 vmlal.u8 q14, d3, d7 695 vrshrn.i16 d2, q15, #6 696 vrshrn.i16 d3, q14, #6 697 subs r12, r12, #32 698 vst1.u8 {q0, q1}, [r0, :128]! 699 bgt 32b 700 add r0, r0, r1 701 subs r4, r4, #1 702 bgt 321b 703 pop {r4-r5,pc} 704endfunc 705 706function blend_v_8bpc_neon, export=1 707 push {r4,lr} 708 ldr r4, [sp, #8] 709 movrel lr, X(obmc_masks) 710 add lr, lr, r3 711 clz r12, r3 712 adr r3, L(blend_v_tbl) 713 sub r12, r12, #26 714 ldr r12, [r3, r12, lsl #2] 715 add r3, r3, r12 716 bx r3 717 718 .align 2 719L(blend_v_tbl): 720 .word 320f - L(blend_v_tbl) + CONFIG_THUMB 721 .word 160f - L(blend_v_tbl) + CONFIG_THUMB 722 .word 80f - L(blend_v_tbl) + CONFIG_THUMB 723 .word 40f - L(blend_v_tbl) + CONFIG_THUMB 724 .word 20f - L(blend_v_tbl) + CONFIG_THUMB 725 72620: 727 vmov.i8 d22, #64 728 vld1.8 {d2[]}, [lr] 729 add r12, r0, r1 730 lsl r1, r1, #1 731 vsub.i8 d3, d22, d2 7322: 733 vld1.16 {d1[0]}, [r2, :16]! 734 vld1.8 {d0[]}, [r0] 735 subs r4, r4, #2 736 vld1.8 {d1[1]}, [r2] 737 vld1.8 {d0[1]}, [r12] 738 vmull.u8 q2, d1, d2 739 vmlal.u8 q2, d0, d3 740 vrshrn.i16 d6, q2, #6 741 add r2, r2, #2 742 vst1.8 {d6[0]}, [r0], r1 743 vst1.8 {d6[1]}, [r12], r1 744 bgt 2b 745 pop {r4,pc} 74640: 747 vmov.i8 d22, #64 748 vld1.32 {d4[]}, [lr, :32] 749 add r12, r0, r1 750 lsl r1, r1, #1 751 vsub.i8 d5, d22, d4 752 sub r1, r1, #2 7534: 754 vld1.u8 {d2}, [r2, :64]! 755 vld1.32 {d0[]}, [r0, :32] 756 vld1.32 {d0[1]}, [r12, :32] 757 subs r4, r4, #2 758 vmull.u8 q3, d2, d4 759 vmlal.u8 q3, d0, d5 760 vrshrn.i16 d20, q3, #6 761 vst1.16 {d20[0]}, [r0, :16]! 762 vst1.16 {d20[2]}, [r12, :16]! 763 vst1.8 {d20[2]}, [r0], r1 764 vst1.8 {d20[6]}, [r12], r1 765 bgt 4b 766 pop {r4,pc} 76780: 768 vmov.i8 d16, #64 769 vld1.u8 {d2}, [lr, :64] 770 add r12, r0, r1 771 lsl r1, r1, #1 772 vsub.i8 d17, d16, d2 773 sub r1, r1, #4 7748: 775 vld1.u8 {d4, d5}, [r2, :128]! 776 vld1.u8 {d0}, [r0, :64] 777 vld1.u8 {d1}, [r12, :64] 778 subs r4, r4, #2 779 vmull.u8 q3, d2, d4 780 vmlal.u8 q3, d0, d17 781 vmull.u8 q10, d2, d5 782 vmlal.u8 q10, d1, d17 783 vrshrn.i16 d22, q3, #6 784 vrshrn.i16 d23, q10, #6 785 vst1.32 {d22[0]}, [r0, :32]! 786 vst1.32 {d23[0]}, [r12, :32]! 787 vst1.16 {d22[2]}, [r0, :16], r1 788 vst1.16 {d23[2]}, [r12, :16], r1 789 bgt 8b 790 pop {r4,pc} 791160: 792 vmov.i8 q12, #64 793 vld1.u8 {q14}, [lr, :128] 794 add r12, r0, r1 795 lsl r1, r1, #1 796 vsub.i8 q11, q12, q14 797 sub r1, r1, #8 79816: 799 vld1.u8 {q1, q2}, [r2, :128]! 800 vld1.u8 {q0}, [r0, :128] 801 subs r4, r4, #2 802 vld1.u8 {q13}, [r12, :128] 803 vmull.u8 q3, d2, d28 804 vmlal.u8 q3, d0, d22 805 vmull.u8 q8, d3, d29 806 vmlal.u8 q8, d1, d23 807 vrshrn.i16 d18, q3, #6 808 vrshrn.i16 d19, q8, #6 809 vmull.u8 q3, d4, d28 810 vmlal.u8 q3, d26, d22 811 vmull.u8 q8, d5, d29 812 vmlal.u8 q8, d27, d23 813 vrshrn.i16 d20, q3, #6 814 vrshrn.i16 d21, q8, #6 815 vst1.u8 {d18}, [r0, :64]! 816 vst1.u8 {d20}, [r12, :64]! 817 vst1.32 {d19[0]}, [r0, :32], r1 818 vst1.32 {d21[0]}, [r12, :32], r1 819 bgt 16b 820 pop {r4,pc} 821320: 822 vmov.i8 q10, #64 823 vld1.u8 {q2, q3}, [lr, :128] 824 vsub.i8 q11, q10, q2 825 vsub.i8 d24, d20, d6 82632: 827 vld1.u8 {q8, q9}, [r2, :128]! 828 vld1.u8 {d0, d1, d2}, [r0, :64] 829 subs r4, r4, #1 830 vmull.u8 q15, d16, d4 831 vmlal.u8 q15, d0, d22 832 vmull.u8 q14, d17, d5 833 vmlal.u8 q14, d1, d23 834 vrshrn.i16 d0, q15, #6 835 vrshrn.i16 d1, q14, #6 836 vmull.u8 q15, d18, d6 837 vmlal.u8 q15, d2, d24 838 vrshrn.i16 d2, q15, #6 839 vst1.u8 {d0, d1, d2}, [r0, :64], r1 840 bgt 32b 841 pop {r4,pc} 842endfunc 843 844 845// This has got the same signature as the put_8tap functions, 846// assumes that the caller has loaded the h argument into r5, 847// and assumes that r8 is set to (clz(w)-24). 848function put_neon 849 adr r9, L(put_tbl) 850 ldr r8, [r9, r8, lsl #2] 851 add r9, r9, r8 852 bx r9 853 854 .align 2 855L(put_tbl): 856 .word 1280f - L(put_tbl) + CONFIG_THUMB 857 .word 640f - L(put_tbl) + CONFIG_THUMB 858 .word 32f - L(put_tbl) + CONFIG_THUMB 859 .word 160f - L(put_tbl) + CONFIG_THUMB 860 .word 8f - L(put_tbl) + CONFIG_THUMB 861 .word 4f - L(put_tbl) + CONFIG_THUMB 862 .word 2f - L(put_tbl) + CONFIG_THUMB 863 8642: 865 vld1.16 {d0[]}, [r2], r3 866 vld1.16 {d1[]}, [r2], r3 867 subs r5, r5, #2 868 vst1.16 {d0[0]}, [r0, :16], r1 869 vst1.16 {d1[0]}, [r0, :16], r1 870 bgt 2b 871 pop {r4-r11,pc} 8724: 873 vld1.32 {d0[]}, [r2], r3 874 vld1.32 {d1[]}, [r2], r3 875 subs r5, r5, #2 876 vst1.32 {d0[0]}, [r0, :32], r1 877 vst1.32 {d1[0]}, [r0, :32], r1 878 bgt 4b 879 pop {r4-r11,pc} 8808: 881 vld1.8 {d0}, [r2], r3 882 vld1.8 {d1}, [r2], r3 883 subs r5, r5, #2 884 vst1.8 {d0}, [r0, :64], r1 885 vst1.8 {d1}, [r0, :64], r1 886 bgt 8b 887 pop {r4-r11,pc} 888160: 889 add r8, r0, r1 890 lsl r1, r1, #1 891 add r9, r2, r3 892 lsl r3, r3, #1 89316: 894 vld1.8 {q0}, [r2], r3 895 vld1.8 {q1}, [r9], r3 896 subs r5, r5, #2 897 vst1.8 {q0}, [r0, :128], r1 898 vst1.8 {q1}, [r8, :128], r1 899 bgt 16b 900 pop {r4-r11,pc} 90132: 902 vld1.8 {q0, q1}, [r2], r3 903 subs r5, r5, #1 904 vst1.8 {q0, q1}, [r0, :128], r1 905 bgt 32b 906 pop {r4-r11,pc} 907640: 908 sub r1, r1, #32 909 sub r3, r3, #32 91064: 911 vld1.8 {q0, q1}, [r2]! 912 vst1.8 {q0, q1}, [r0, :128]! 913 vld1.8 {q2, q3}, [r2], r3 914 subs r5, r5, #1 915 vst1.8 {q2, q3}, [r0, :128], r1 916 bgt 64b 917 pop {r4-r11,pc} 9181280: 919 sub r1, r1, #96 920 sub r3, r3, #96 921128: 922 vld1.8 {q8, q9}, [r2]! 923 vst1.8 {q8, q9}, [r0, :128]! 924 vld1.8 {q10, q11}, [r2]! 925 vst1.8 {q10, q11}, [r0, :128]! 926 vld1.8 {q12, q13}, [r2]! 927 vst1.8 {q12, q13}, [r0, :128]! 928 vld1.8 {q14, q15}, [r2], r3 929 subs r5, r5, #1 930 vst1.8 {q14, q15}, [r0, :128], r1 931 bgt 128b 932 pop {r4-r11,pc} 933endfunc 934 935 936// This has got the same signature as the put_8tap functions, 937// assumes that the caller has loaded the h argument into r4, 938// and assumes that r8 is set to (clz(w)-24), and r7 to w*2. 939function prep_neon 940 adr r9, L(prep_tbl) 941 ldr r8, [r9, r8, lsl #2] 942 add r9, r9, r8 943 bx r9 944 945 .align 2 946L(prep_tbl): 947 .word 1280f - L(prep_tbl) + CONFIG_THUMB 948 .word 640f - L(prep_tbl) + CONFIG_THUMB 949 .word 320f - L(prep_tbl) + CONFIG_THUMB 950 .word 160f - L(prep_tbl) + CONFIG_THUMB 951 .word 8f - L(prep_tbl) + CONFIG_THUMB 952 .word 4f - L(prep_tbl) + CONFIG_THUMB 953 9544: 955 vld1.32 {d0[]}, [r1], r2 956 vld1.32 {d2[]}, [r1], r2 957 subs r4, r4, #2 958 vshll.u8 q0, d0, #4 959 vshll.u8 q1, d2, #4 960 vst1.16 {d1, d2}, [r0, :64]! 961 bgt 4b 962 pop {r4-r11,pc} 9638: 964 vld1.8 {d0}, [r1], r2 965 vld1.8 {d2}, [r1], r2 966 subs r4, r4, #2 967 vshll.u8 q0, d0, #4 968 vshll.u8 q1, d2, #4 969 vst1.16 {q0, q1}, [r0, :128]! 970 bgt 8b 971 pop {r4-r11,pc} 972160: 973 add r9, r1, r2 974 lsl r2, r2, #1 975 add r8, r0, r7 976 lsl r7, r7, #1 97716: 978 vld1.8 {q2}, [r1], r2 979 vld1.8 {q3}, [r9], r2 980 subs r4, r4, #2 981 vshll.u8 q0, d4, #4 982 vshll.u8 q1, d5, #4 983 vshll.u8 q2, d6, #4 984 vshll.u8 q3, d7, #4 985 vst1.16 {q0, q1}, [r0, :128], r7 986 vst1.16 {q2, q3}, [r8, :128], r7 987 bgt 16b 988 pop {r4-r11,pc} 989320: 990 add r8, r0, r3 99132: 992 vld1.8 {q0, q1}, [r1], r2 993 subs r4, r4, #2 994 vshll.u8 q8, d0, #4 995 vshll.u8 q9, d1, #4 996 vld1.8 {q2, q3}, [r1], r2 997 vshll.u8 q10, d2, #4 998 vshll.u8 q11, d3, #4 999 vshll.u8 q12, d4, #4 1000 vst1.16 {q8, q9}, [r0, :128], r7 1001 vshll.u8 q13, d5, #4 1002 vst1.16 {q10, q11}, [r8, :128], r7 1003 vshll.u8 q14, d6, #4 1004 vst1.16 {q12, q13}, [r0, :128], r7 1005 vshll.u8 q15, d7, #4 1006 vst1.16 {q14, q15}, [r8, :128], r7 1007 bgt 32b 1008 pop {r4-r11,pc} 1009640: 1010 sub r2, r2, #32 1011 add r8, r0, #32 1012 mov r6, #64 101364: 1014 vld1.8 {q0, q1}, [r1]! 1015 subs r4, r4, #1 1016 vshll.u8 q8, d0, #4 1017 vshll.u8 q9, d1, #4 1018 vld1.8 {q2, q3}, [r1], r2 1019 vshll.u8 q10, d2, #4 1020 vshll.u8 q11, d3, #4 1021 vshll.u8 q12, d4, #4 1022 vst1.16 {q8, q9}, [r0, :128], r6 1023 vshll.u8 q13, d5, #4 1024 vshll.u8 q14, d6, #4 1025 vst1.16 {q10, q11}, [r8, :128], r6 1026 vshll.u8 q15, d7, #4 1027 vst1.16 {q12, q13}, [r0, :128], r6 1028 vst1.16 {q14, q15}, [r8, :128], r6 1029 bgt 64b 1030 pop {r4-r11,pc} 10311280: 1032 sub r2, r2, #96 1033 add r8, r0, #32 1034 mov r6, #64 1035128: 1036 vld1.8 {q0, q1}, [r1]! 1037 vld1.8 {q2, q3}, [r1]! 1038 vshll.u8 q10, d0, #4 1039 vshll.u8 q11, d1, #4 1040 vshll.u8 q12, d2, #4 1041 vshll.u8 q13, d3, #4 1042 vshll.u8 q14, d4, #4 1043 vshll.u8 q15, d5, #4 1044 vld1.8 {q8, q9}, [r1]! 1045 vst1.16 {q10, q11}, [r0, :128], r6 1046 vst1.16 {q12, q13}, [r8, :128], r6 1047 vshll.u8 q0, d6, #4 1048 vshll.u8 q1, d7, #4 1049 vshll.u8 q2, d16, #4 1050 vshll.u8 q3, d17, #4 1051 vshll.u8 q8, d18, #4 1052 vshll.u8 q9, d19, #4 1053 vld1.8 {q10, q11}, [r1], r2 1054 vst1.16 {q14, q15}, [r0, :128], r6 1055 vst1.16 {q0, q1}, [r8, :128], r6 1056 vshll.u8 q12, d20, #4 1057 vshll.u8 q13, d21, #4 1058 vshll.u8 q14, d22, #4 1059 vshll.u8 q15, d23, #4 1060 subs r4, r4, #1 1061 vst1.16 {q2, q3}, [r0, :128], r6 1062 vst1.16 {q8, q9}, [r8, :128], r6 1063 vst1.16 {q12, q13}, [r0, :128], r6 1064 vst1.16 {q14, q15}, [r8, :128], r6 1065 bgt 128b 1066 pop {r4-r11,pc} 1067endfunc 1068 1069 1070.macro load_slice s0, s1, strd, wd, d0, d1, d2, d3, d4, d5, d6 1071 vld1.\wd {\d0[]}, [\s0], \strd 1072 vld1.\wd {\d1[]}, [\s1], \strd 1073.ifnb \d2 1074 vld1.\wd {\d2[]}, [\s0], \strd 1075 vld1.\wd {\d3[]}, [\s1], \strd 1076.endif 1077.ifnb \d4 1078 vld1.\wd {\d4[]}, [\s0], \strd 1079.endif 1080.ifnb \d5 1081 vld1.\wd {\d5[]}, [\s1], \strd 1082.endif 1083.ifnb \d6 1084 vld1.\wd {\d6[]}, [\s0], \strd 1085.endif 1086.endm 1087.macro load_reg s0, s1, strd, d0, d1, d2, d3, d4, d5, d6 1088 vld1.8 {\d0}, [\s0], \strd 1089 vld1.8 {\d1}, [\s1], \strd 1090.ifnb \d2 1091 vld1.8 {\d2}, [\s0], \strd 1092 vld1.8 {\d3}, [\s1], \strd 1093.endif 1094.ifnb \d4 1095 vld1.8 {\d4}, [\s0], \strd 1096.endif 1097.ifnb \d5 1098 vld1.8 {\d5}, [\s1], \strd 1099.endif 1100.ifnb \d6 1101 vld1.8 {\d6}, [\s0], \strd 1102.endif 1103.endm 1104.macro load_16 s0, s1, strd, d0, d1, d2, d3, d4, d5, d6 1105 load_slice \s0, \s1, \strd, 16, \d0, \d1, \d2, \d3, \d4, \d5, \d6 1106.endm 1107.macro load_32 s0, s1, strd, d0, d1, d2, d3, d4, d5, d6 1108 load_slice \s0, \s1, \strd, 32, \d0, \d1, \d2, \d3, \d4, \d5, \d6 1109.endm 1110.macro interleave_1_16 r0, r1, r2, r3, r4 1111 vext.8 \r0, \r0, \r1, #6 1112 vext.8 \r1, \r1, \r2, #6 1113.ifnb \r3 1114 vext.8 \r2, \r2, \r3, #6 1115 vext.8 \r3, \r3, \r4, #6 1116.endif 1117.endm 1118.macro interleave_1_32 r0, r1, r2, r3, r4 1119 vext.8 \r0, \r0, \r1, #4 1120 vext.8 \r1, \r1, \r2, #4 1121.ifnb \r3 1122 vext.8 \r2, \r2, \r3, #4 1123 vext.8 \r3, \r3, \r4, #4 1124.endif 1125.endm 1126.macro vmovl_u8 q0, d0, q1, d1, q2, d2, q3, d3, q4, d4, q5, d5, q6, d6 1127 vmovl.u8 \q0, \d0 1128 vmovl.u8 \q1, \d1 1129.ifnb \q2 1130 vmovl.u8 \q2, \d2 1131 vmovl.u8 \q3, \d3 1132.endif 1133.ifnb \q4 1134 vmovl.u8 \q4, \d4 1135.endif 1136.ifnb \q5 1137 vmovl.u8 \q5, \d5 1138.endif 1139.ifnb \q6 1140 vmovl.u8 \q6, \d6 1141.endif 1142.endm 1143.macro mul_mla_4 d, s0, s1, s2, s3 1144 vmul.s16 \d, \s0, d0[0] 1145 vmla.s16 \d, \s1, d0[1] 1146 vmla.s16 \d, \s2, d0[2] 1147 vmla.s16 \d, \s3, d0[3] 1148.endm 1149.macro mul_mla_8_0 d0, s0, s1, s2, s3, s4, s5, s6, s7 1150 vmul.s16 \d0, \s0, d0[0] 1151 vmla.s16 \d0, \s1, d0[1] 1152 vmla.s16 \d0, \s2, d0[2] 1153 vmla.s16 \d0, \s3, d0[3] 1154 vmla.s16 \d0, \s4, d1[0] 1155 vmla.s16 \d0, \s5, d1[1] 1156 vmla.s16 \d0, \s6, d1[2] 1157 vmla.s16 \d0, \s7, d1[3] 1158.endm 1159.macro mul_mla_8_1 d0, d1, s0, s1, s2, s3, s4, s5, s6, s7, s8 1160 vmul.s16 \d0, \s0, d0[0] 1161 vmla.s16 \d0, \s1, d0[1] 1162 vmla.s16 \d0, \s2, d0[2] 1163 vmla.s16 \d0, \s3, d0[3] 1164 vmla.s16 \d0, \s4, d1[0] 1165 vmla.s16 \d0, \s5, d1[1] 1166 vmla.s16 \d0, \s6, d1[2] 1167 vmla.s16 \d0, \s7, d1[3] 1168 vmul.s16 \d1, \s1, d0[0] 1169 vmla.s16 \d1, \s2, d0[1] 1170 vmla.s16 \d1, \s3, d0[2] 1171 vmla.s16 \d1, \s4, d0[3] 1172 vmla.s16 \d1, \s5, d1[0] 1173 vmla.s16 \d1, \s6, d1[1] 1174 vmla.s16 \d1, \s7, d1[2] 1175 vmla.s16 \d1, \s8, d1[3] 1176.endm 1177.macro mul_mla_8_2 d0, d1, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9 1178 vmul.s16 \d0, \s0, d0[0] 1179 vmla.s16 \d0, \s1, d0[1] 1180 vmla.s16 \d0, \s2, d0[2] 1181 vmla.s16 \d0, \s3, d0[3] 1182 vmla.s16 \d0, \s4, d1[0] 1183 vmla.s16 \d0, \s5, d1[1] 1184 vmla.s16 \d0, \s6, d1[2] 1185 vmla.s16 \d0, \s7, d1[3] 1186 vmul.s16 \d1, \s2, d0[0] 1187 vmla.s16 \d1, \s3, d0[1] 1188 vmla.s16 \d1, \s4, d0[2] 1189 vmla.s16 \d1, \s5, d0[3] 1190 vmla.s16 \d1, \s6, d1[0] 1191 vmla.s16 \d1, \s7, d1[1] 1192 vmla.s16 \d1, \s8, d1[2] 1193 vmla.s16 \d1, \s9, d1[3] 1194.endm 1195.macro vqrshrun_s16 shift, q0, d0, q1, d1, q2, d2, q3, d3 1196 vqrshrun.s16 \d0, \q0, #\shift 1197.ifnb \q1 1198 vqrshrun.s16 \d1, \q1, #\shift 1199.endif 1200.ifnb \q2 1201 vqrshrun.s16 \d2, \q2, #\shift 1202 vqrshrun.s16 \d3, \q3, #\shift 1203.endif 1204.endm 1205.macro vrshr_s16 shift, r0, r1, r2, r3 1206 vrshr.s16 \r0, \r0, #\shift 1207.ifnb \r1 1208 vrshr.s16 \r1, \r1, #\shift 1209.endif 1210.ifnb \r2 1211 vrshr.s16 \r2, \r2, #\shift 1212 vrshr.s16 \r3, \r3, #\shift 1213.endif 1214.endm 1215.macro st_16 strd, reg, lanes 1216 vst1.16 {\reg[0]}, [r0, :16], \strd 1217 vst1.16 {\reg[1]}, [r8, :16], \strd 1218.if \lanes > 2 1219 vst1.16 {\reg[2]}, [r0, :16], \strd 1220 vst1.16 {\reg[3]}, [r8, :16], \strd 1221.endif 1222.endm 1223.macro st_32 strd, r0, r1 1224 vst1.32 {\r0[0]}, [r0, :32], \strd 1225 vst1.32 {\r0[1]}, [r8, :32], \strd 1226.ifnb \r1 1227 vst1.32 {\r1[0]}, [r0, :32], \strd 1228 vst1.32 {\r1[1]}, [r8, :32], \strd 1229.endif 1230.endm 1231.macro st_reg strd, align, r0, r1, r2, r3, r4, r5, r6, r7 1232 vst1.8 {\r0}, [r0, \align], \strd 1233 vst1.8 {\r1}, [r8, \align], \strd 1234.ifnb \r2 1235 vst1.8 {\r2}, [r0, \align], \strd 1236 vst1.8 {\r3}, [r8, \align], \strd 1237.endif 1238.ifnb \r4 1239 vst1.8 {\r4}, [r0, \align], \strd 1240 vst1.8 {\r5}, [r8, \align], \strd 1241 vst1.8 {\r6}, [r0, \align], \strd 1242 vst1.8 {\r7}, [r8, \align], \strd 1243.endif 1244.endm 1245.macro shift_store_4 type, strd, q0, d0, d1, q1, d2, d3 1246.ifc \type, put 1247 vqrshrun_s16 6, \q0, \d0, \q1, \d2 1248 st_32 \strd, \d0, \d2 1249.else 1250 vrshr_s16 2, \q0, \q1 1251 st_reg \strd, :64, \d0, \d1, \d2, \d3 1252.endif 1253.endm 1254.macro shift_store_8 type, strd, q0, d0, q1, d1, q2, d2, q3, d3 1255.ifc \type, put 1256 vqrshrun_s16 6, \q0, \d0, \q1, \d1, \q2, \d2, \q3, \d3 1257 st_reg \strd, :64, \d0, \d1, \d2, \d3 1258.else 1259 vrshr_s16 2, \q0, \q1, \q2, \q3 1260 st_reg \strd, :128,\q0, \q1, \q2, \q3 1261.endif 1262.endm 1263.macro shift_store_16 type, strd, q0, d0, d1, q1, q2, d4, d5, q3 1264.ifc \type, put 1265 vqrshrun.s16 \d0, \q0, #6 1266 vqrshrun.s16 \d1, \q1, #6 1267 vqrshrun.s16 \d4, \q2, #6 1268 vqrshrun.s16 \d5, \q3, #6 1269 st_reg \strd, :128, \q0, \q2 1270.else 1271 vrshr_s16 2, \q0, \q1, \q2, \q3 1272 vst1.16 {\q0, \q1}, [r0, :128], \strd 1273 vst1.16 {\q2, \q3}, [r8, :128], \strd 1274.endif 1275.endm 1276 1277.macro make_8tap_fn op, type, type_h, type_v 1278function \op\()_8tap_\type\()_8bpc_neon, export=1 1279 push {r4-r11,lr} 1280 movw r8, \type_h 1281 movw r9, \type_v 1282 b \op\()_8tap_neon 1283endfunc 1284.endm 1285 1286// No spaces in these expressions, due to gas-preprocessor. 1287#define REGULAR ((0*15<<7)|3*15) 1288#define SMOOTH ((1*15<<7)|4*15) 1289#define SHARP ((2*15<<7)|3*15) 1290 1291.macro filter_fn type, dst, d_strd, src, s_strd, w, h, mx, my, ds2, sr2, shift_hv 1292make_8tap_fn \type, regular, REGULAR, REGULAR 1293make_8tap_fn \type, regular_smooth, REGULAR, SMOOTH 1294make_8tap_fn \type, regular_sharp, REGULAR, SHARP 1295make_8tap_fn \type, smooth, SMOOTH, SMOOTH 1296make_8tap_fn \type, smooth_regular, SMOOTH, REGULAR 1297make_8tap_fn \type, smooth_sharp, SMOOTH, SHARP 1298make_8tap_fn \type, sharp, SHARP, SHARP 1299make_8tap_fn \type, sharp_regular, SHARP, REGULAR 1300make_8tap_fn \type, sharp_smooth, SHARP, SMOOTH 1301 1302function \type\()_8tap_neon 1303 ldrd r4, r5, [sp, #36] 1304 ldrd r6, r7, [sp, #44] 1305 movw r10, #0x4081 // (1 << 14) | (1 << 7) | (1 << 0) 1306 mul \mx, \mx, r10 1307 mul \my, \my, r10 1308 add \mx, \mx, r8 // mx, 8tap_h, 4tap_h 1309 add \my, \my, r9 // my, 8tap_v, 4tap_v 1310.ifc \type, prep 1311 lsl \d_strd, \w, #1 1312.endif 1313 1314 clz r8, \w 1315 tst \mx, #(0x7f << 14) 1316 sub r8, r8, #24 1317 movrel r10, X(mc_subpel_filters), -8 1318 bne L(\type\()_8tap_h) 1319 tst \my, #(0x7f << 14) 1320 bne L(\type\()_8tap_v) 1321 b \type\()_neon 1322 1323L(\type\()_8tap_h): 1324 cmp \w, #4 1325 ubfx r9, \mx, #7, #7 1326 and \mx, \mx, #0x7f 1327 it gt 1328 movgt \mx, r9 1329 tst \my, #(0x7f << 14) 1330 add \mx, r10, \mx, lsl #3 1331 bne L(\type\()_8tap_hv) 1332 1333 adr r9, L(\type\()_8tap_h_tbl) 1334 ldr r8, [r9, r8, lsl #2] 1335 add r9, r9, r8 1336 bx r9 1337 1338 .align 2 1339L(\type\()_8tap_h_tbl): 1340 .word 1280f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1341 .word 640f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1342 .word 320f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1343 .word 160f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1344 .word 80f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1345 .word 40f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1346 .word 20f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1347 134820: // 2xN h 1349.ifc \type, put 1350 add \mx, \mx, #2 1351 vld1.32 {d0[]}, [\mx] 1352 sub \src, \src, #1 1353 add \ds2, \dst, \d_strd 1354 add \sr2, \src, \s_strd 1355 lsl \d_strd, \d_strd, #1 1356 lsl \s_strd, \s_strd, #1 1357 vmovl.s8 q0, d0 13582: 1359 vld1.8 {d4}, [\src], \s_strd 1360 vld1.8 {d6}, [\sr2], \s_strd 1361 vmovl.u8 q2, d4 1362 vmovl.u8 q3, d6 1363 vext.8 d5, d4, d5, #2 1364 vext.8 d7, d6, d7, #2 1365 subs \h, \h, #2 1366 vtrn.32 d4, d6 1367 vtrn.32 d5, d7 1368 vmul.s16 d2, d4, d0[0] 1369 vmla.s16 d2, d5, d0[1] 1370 vmla.s16 d2, d6, d0[2] 1371 vmla.s16 d2, d7, d0[3] 1372 vrshr.s16 d2, d2, #2 1373 vqrshrun.s16 d2, q1, #4 1374 vst1.16 {d2[0]}, [\dst, :16], \d_strd 1375 vst1.16 {d2[1]}, [\ds2, :16], \d_strd 1376 bgt 2b 1377 pop {r4-r11,pc} 1378.endif 1379 138040: // 4xN h 1381 add \mx, \mx, #2 1382 vld1.32 {d0[]}, [\mx] 1383 sub \src, \src, #1 1384 add \ds2, \dst, \d_strd 1385 add \sr2, \src, \s_strd 1386 lsl \d_strd, \d_strd, #1 1387 lsl \s_strd, \s_strd, #1 1388 vmovl.s8 q0, d0 13894: 1390 vld1.8 {d16}, [\src], \s_strd 1391 vld1.8 {d24}, [\sr2], \s_strd 1392 vmovl.u8 q8, d16 1393 vmovl.u8 q12, d24 1394 vext.8 d18, d16, d17, #2 1395 vext.8 d20, d16, d17, #4 1396 vext.8 d22, d16, d17, #6 1397 vext.8 d26, d24, d25, #2 1398 vext.8 d28, d24, d25, #4 1399 vext.8 d30, d24, d25, #6 1400 subs \h, \h, #2 1401 vmul.s16 d4, d16, d0[0] 1402 vmla.s16 d4, d18, d0[1] 1403 vmla.s16 d4, d20, d0[2] 1404 vmla.s16 d4, d22, d0[3] 1405 vmul.s16 d5, d24, d0[0] 1406 vmla.s16 d5, d26, d0[1] 1407 vmla.s16 d5, d28, d0[2] 1408 vmla.s16 d5, d30, d0[3] 1409 vrshr.s16 q2, q2, #2 1410.ifc \type, put 1411 vqrshrun.s16 d4, q2, #4 1412 vst1.32 {d4[0]}, [\dst, :32], \d_strd 1413 vst1.32 {d4[1]}, [\ds2, :32], \d_strd 1414.else 1415 vst1.16 {d4}, [\dst, :64], \d_strd 1416 vst1.16 {d5}, [\ds2, :64], \d_strd 1417.endif 1418 bgt 4b 1419 pop {r4-r11,pc} 1420 142180: // 8xN h 1422 vld1.8 {d0}, [\mx, :64] 1423 sub \src, \src, #3 1424 add \ds2, \dst, \d_strd 1425 add \sr2, \src, \s_strd 1426 lsl \d_strd, \d_strd, #1 1427 lsl \s_strd, \s_strd, #1 1428 vmovl.s8 q0, d0 14298: 1430 vld1.8 {q8}, [\src], \s_strd 1431 vld1.8 {q12}, [\sr2], \s_strd 1432 vmovl.u8 q9, d17 1433 vmovl.u8 q8, d16 1434 vmovl.u8 q13, d25 1435 vmovl.u8 q12, d24 1436 1437 vmul.s16 q10, q8, d0[0] 1438 vmul.s16 q14, q12, d0[0] 1439.irpc i, 1234567 1440 vext.8 q11, q8, q9, #(2*\i) 1441 vext.8 q15, q12, q13, #(2*\i) 1442.if \i < 4 1443 vmla.s16 q10, q11, d0[\i] 1444 vmla.s16 q14, q15, d0[\i] 1445.else 1446 vmla.s16 q10, q11, d1[\i-4] 1447 vmla.s16 q14, q15, d1[\i-4] 1448.endif 1449.endr 1450 subs \h, \h, #2 1451 vrshr.s16 q10, q10, #2 1452 vrshr.s16 q14, q14, #2 1453.ifc \type, put 1454 vqrshrun.s16 d20, q10, #4 1455 vqrshrun.s16 d28, q14, #4 1456 vst1.8 {d20}, [\dst, :64], \d_strd 1457 vst1.8 {d28}, [\ds2, :64], \d_strd 1458.else 1459 vst1.16 {q10}, [\dst, :128], \d_strd 1460 vst1.16 {q14}, [\ds2, :128], \d_strd 1461.endif 1462 bgt 8b 1463 pop {r4-r11,pc} 1464 1465160: 1466320: 1467640: 14681280: // 16xN, 32xN, ... h 1469 // This could be done without touching q4-q6, by using only 1470 // one temporary for vext in the loop. That's slower on A7 and A53, 1471 // (but surprisingly, marginally faster on A8 and A73). 1472 vpush {q4-q6} 1473 vld1.8 {d0}, [\mx, :64] 1474 sub \src, \src, #3 1475 add \ds2, \dst, \d_strd 1476 add \sr2, \src, \s_strd 1477 lsl \s_strd, \s_strd, #1 1478 vmovl.s8 q0, d0 1479 1480 sub \s_strd, \s_strd, \w 1481 sub \s_strd, \s_strd, #8 1482.ifc \type, put 1483 lsl \d_strd, \d_strd, #1 1484 sub \d_strd, \d_strd, \w 1485.endif 1486161: 1487 vld1.8 {d16, d17, d18}, [\src]! 1488 vld1.8 {d24, d25, d26}, [\sr2]! 1489 mov \mx, \w 1490 vmovl.u8 q10, d18 1491 vmovl.u8 q9, d17 1492 vmovl.u8 q8, d16 1493 vmovl.u8 q14, d26 1494 vmovl.u8 q13, d25 1495 vmovl.u8 q12, d24 1496 149716: 1498 vmul.s16 q1, q8, d0[0] 1499 vmul.s16 q2, q9, d0[0] 1500 vmul.s16 q3, q12, d0[0] 1501 vmul.s16 q4, q13, d0[0] 1502.irpc i, 1234567 1503 vext.8 q5, q8, q9, #(2*\i) 1504 vext.8 q6, q9, q10, #(2*\i) 1505 vext.8 q11, q12, q13, #(2*\i) 1506 vext.8 q15, q13, q14, #(2*\i) 1507.if \i < 4 1508 vmla.s16 q1, q5, d0[\i] 1509 vmla.s16 q2, q6, d0[\i] 1510 vmla.s16 q3, q11, d0[\i] 1511 vmla.s16 q4, q15, d0[\i] 1512.else 1513 vmla.s16 q1, q5, d1[\i-4] 1514 vmla.s16 q2, q6, d1[\i-4] 1515 vmla.s16 q3, q11, d1[\i-4] 1516 vmla.s16 q4, q15, d1[\i-4] 1517.endif 1518.endr 1519 vrshr.s16 q1, q1, #2 1520 vrshr.s16 q2, q2, #2 1521 vrshr.s16 q3, q3, #2 1522 vrshr.s16 q4, q4, #2 1523 subs \mx, \mx, #16 1524.ifc \type, put 1525 vqrshrun.s16 d2, q1, #4 1526 vqrshrun.s16 d3, q2, #4 1527 vqrshrun.s16 d4, q3, #4 1528 vqrshrun.s16 d5, q4, #4 1529 vst1.8 {q1}, [\dst, :128]! 1530 vst1.8 {q2}, [\ds2, :128]! 1531.else 1532 vst1.16 {q1, q2}, [\dst, :128]! 1533 vst1.16 {q3, q4}, [\ds2, :128]! 1534.endif 1535 ble 9f 1536 1537 vmov q8, q10 1538 vmov q12, q14 1539 vld1.8 {d18, d19}, [\src]! 1540 vld1.8 {d26, d27}, [\sr2]! 1541 vmovl.u8 q10, d19 1542 vmovl.u8 q9, d18 1543 vmovl.u8 q14, d27 1544 vmovl.u8 q13, d26 1545 b 16b 1546 15479: 1548 add \dst, \dst, \d_strd 1549 add \ds2, \ds2, \d_strd 1550 add \src, \src, \s_strd 1551 add \sr2, \sr2, \s_strd 1552 1553 subs \h, \h, #2 1554 bgt 161b 1555 vpop {q4-q6} 1556 pop {r4-r11,pc} 1557 1558L(\type\()_8tap_v): 1559 cmp \h, #4 1560 ubfx r9, \my, #7, #7 1561 and \my, \my, #0x7f 1562 it gt 1563 movgt \my, r9 1564 add \my, r10, \my, lsl #3 1565 1566 adr r9, L(\type\()_8tap_v_tbl) 1567 ldr r8, [r9, r8, lsl #2] 1568 add r9, r9, r8 1569 bx r9 1570 1571 .align 2 1572L(\type\()_8tap_v_tbl): 1573 .word 1280f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1574 .word 640f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1575 .word 320f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1576 .word 160f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1577 .word 80f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1578 .word 40f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1579 .word 20f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1580 158120: // 2xN v 1582.ifc \type, put 1583 bgt 28f 1584 1585 cmp \h, #2 1586 add \my, \my, #2 1587 vld1.32 {d0[]}, [\my] 1588 sub \src, \src, \s_strd 1589 add \ds2, \dst, \d_strd 1590 add \sr2, \src, \s_strd 1591 lsl \s_strd, \s_strd, #1 1592 lsl \d_strd, \d_strd, #1 1593 vmovl.s8 q0, d0 1594 1595 // 2x2 v 1596 load_16 \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1597 interleave_1_16 d1, d2, d3, d4, d5 1598 bgt 24f 1599 vmovl_u8 q8, d1, q9, d2, q10, d3, q11, d4 1600 mul_mla_4 d6, d16, d18, d20, d22 1601 vqrshrun_s16 6, q3, d6 1602 st_16 \d_strd, d6, 2 1603 pop {r4-r11,pc} 1604 160524: // 2x4 v 1606 load_16 \sr2, \src, \s_strd, d6, d7 1607 interleave_1_16 d5, d6, d7 1608 vmovl_u8 q8, d1, q9, d2, q10, d3, q11, d4, q12, d5, q13, d6 1609 vmov d17, d20 1610 vmov d19, d22 1611 vmov d21, d24 1612 vmov d23, d26 1613 mul_mla_4 q3, q8, q9, q10, q11 1614 vqrshrun_s16 6, q3, d6 1615 st_16 \d_strd, d6, 4 1616 pop {r4-r11,pc} 1617 161828: // 2x6, 2x8, 2x12, 2x16 v 1619 vpush {q4-q7} 1620 vld1.8 {d0}, [\my, :64] 1621 sub \sr2, \src, \s_strd, lsl #1 1622 add \ds2, \dst, \d_strd 1623 sub \src, \sr2, \s_strd 1624 lsl \d_strd, \d_strd, #1 1625 lsl \s_strd, \s_strd, #1 1626 vmovl.s8 q0, d0 1627 1628 load_16 \src, \sr2, \s_strd, d2, d4, d6, d8, d10, d12, d14 1629 interleave_1_16 d2, d4, d6, d8, d10 1630 interleave_1_16 d10, d12, d14 1631 vmovl_u8 q1, d2, q2, d4, q3, d6, q4, d8, q5, d10, q6, d12 1632 vmov d3, d6 1633 vmov d5, d8 1634 vmov d7, d10 1635 vmov d9, d12 1636216: 1637 subs \h, \h, #4 1638 load_16 \sr2, \src, \s_strd, d16, d18, d20, d22 1639 interleave_1_16 d14, d16, d18, d20, d22 1640 vmovl_u8 q7, d14, q8, d16, q9, d18, q10, d20 1641 vmov d11, d14 1642 vmov d13, d16 1643 vmov d15, d18 1644 vmov d17, d20 1645 mul_mla_8_0 q1, q1, q2, q3, q4, q5, q6, q7, q8 1646 vqrshrun_s16 6, q1, d2 1647 st_16 \d_strd, d2, 4 1648 ble 0f 1649 cmp \h, #2 1650 vmov q1, q5 1651 vmov q2, q6 1652 vmov q3, q7 1653 vmov q4, q8 1654 vmov q5, q9 1655 vmov q6, q10 1656 vmov d14, d22 1657 beq 26f 1658 b 216b 165926: 1660 load_16 \sr2, \src, \s_strd, d16, d18 1661 interleave_1_16 d14, d16, d18 1662 vmovl_u8 q7, d14, q8, d16 1663 vmov d11, d14 1664 vmov d13, d16 1665 mul_mla_8_0 d2, d2, d4, d6, d8, d10, d12, d14, d16 1666 vqrshrun_s16 6, q1, d2 1667 st_16 \d_strd, d2, 2 16680: 1669 vpop {q4-q7} 1670 pop {r4-r11,pc} 1671.endif 1672 167340: 1674 bgt 480f 1675 1676 // 4x2, 4x4 v 1677 cmp \h, #2 1678 add \my, \my, #2 1679 vld1.32 {d0[]}, [\my] 1680 sub \src, \src, \s_strd 1681 add \ds2, \dst, \d_strd 1682 add \sr2, \src, \s_strd 1683 lsl \s_strd, \s_strd, #1 1684 lsl \d_strd, \d_strd, #1 1685 vmovl.s8 q0, d0 1686 1687 load_32 \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1688 interleave_1_32 d1, d2, d3, d4, d5 1689 vmovl_u8 q8, d1, q9, d2, q10, d3, q11, d4 1690 mul_mla_4 q3, q8, q9, q10, q11 1691 shift_store_4 \type, \d_strd, q3, d6, d7 1692 ble 0f 1693 load_32 \sr2, \src, \s_strd, d6, d7 1694 interleave_1_32 d5, d6, d7 1695 vmovl_u8 q12, d5, q13, d6 1696 mul_mla_4 q3, q10, q11, q12, q13 1697 shift_store_4 \type, \d_strd, q3, d6, d7 16980: 1699 pop {r4-r11,pc} 1700 1701480: // 4x6, 4x8, 4x12, 4x16 v 1702 vpush {q4} 1703 vld1.8 {d0}, [\my, :64] 1704 sub \sr2, \src, \s_strd, lsl #1 1705 add \ds2, \dst, \d_strd 1706 sub \src, \sr2, \s_strd 1707 lsl \s_strd, \s_strd, #1 1708 lsl \d_strd, \d_strd, #1 1709 vmovl.s8 q0, d0 1710 1711 load_32 \src, \sr2, \s_strd, d2, d4, d6, d8, d16, d18, d20 1712 interleave_1_32 d2, d4, d6 1713 interleave_1_32 d6, d8, d16, d18, d20 1714 vmovl_u8 q1, d2, q2, d4, q3, d6, q4, d8, q8, d16, q9, d18 1715 171648: 1717 subs \h, \h, #4 1718 load_32 \sr2, \src, \s_strd, d22, d24, d26, d28 1719 interleave_1_32 d20, d22, d24, d26, d28 1720 vmovl_u8 q10, d20, q11, d22, q12, d24, q13, d26 1721 mul_mla_8_2 q1, q2, q1, q2, q3, q4, q8, q9, q10, q11, q12, q13 1722 shift_store_4 \type, \d_strd, q1, d2, d3, q2, d4, d5 1723 ble 0f 1724 load_32 \sr2, \src, \s_strd, d30, d2 1725 subs \h, \h, #2 1726 interleave_1_32 d28, d30, d2 1727 vmovl_u8 q14, d28, q15, d30 1728 mul_mla_8_0 q8, q8, q9, q10, q11, q12, q13, q14, q15 1729 shift_store_4 \type, \d_strd, q8, d16, d17 1730 ble 0f 1731 load_32 \sr2, \src, \s_strd, d4, d6 1732 subs \h, \h, #2 1733 interleave_1_32 d2, d4, d6 1734 vmovl_u8 q1, d2, q2, d4 1735 mul_mla_8_0 q9, q10, q11, q12, q13, q14, q15, q1, q2 1736 shift_store_4 \type, \d_strd, q9, d18, d19 1737 ble 0f 1738 subs \h, \h, #4 1739 load_32 \sr2, \src, \s_strd, d8, d16, d18, d20 1740 interleave_1_32 d6, d8, d16, d18, d20 1741 vmovl_u8 q3, d6, q4, d8, q8, d16, q9, d18 1742 mul_mla_8_2 q12, q13, q12, q13, q14, q15, q1, q2, q3, q4, q8, q9 1743 shift_store_4 \type, \d_strd, q12, d24, d25, q13, d26, d27 1744 bgt 48b 17450: 1746 vpop {q4} 1747 pop {r4-r11,pc} 1748 174980: 1750 bgt 880f 1751 1752 // 8x2, 8x4 v 1753 cmp \h, #2 1754 add \my, \my, #2 1755 vld1.32 {d0[]}, [\my] 1756 sub \src, \src, \s_strd 1757 add \ds2, \dst, \d_strd 1758 add \sr2, \src, \s_strd 1759 lsl \s_strd, \s_strd, #1 1760 lsl \d_strd, \d_strd, #1 1761 vmovl.s8 q0, d0 1762 1763 load_reg \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1764 vmovl_u8 q8, d1, q9, d2, q10, d3, q11, d4, q12, d5 1765 mul_mla_4 q1, q8, q9, q10, q11 1766 mul_mla_4 q2, q9, q10, q11, q12 1767 shift_store_8 \type, \d_strd, q1, d2, q2, d4 1768 ble 0f 1769 load_reg \sr2, \src, \s_strd, d6, d7 1770 vmovl_u8 q13, d6, q14, d7 1771 mul_mla_4 q1, q10, q11, q12, q13 1772 mul_mla_4 q2, q11, q12, q13, q14 1773 shift_store_8 \type, \d_strd, q1, d2, q2, d4 17740: 1775 pop {r4-r11,pc} 1776 1777880: // 8x6, 8x8, 8x16, 8x32 v 17781680: // 16x8, 16x16, ... 1779320: // 32x8, 32x16, ... 1780640: 17811280: 1782 vpush {q4} 1783 vld1.8 {d0}, [\my, :64] 1784 sub \src, \src, \s_strd 1785 sub \src, \src, \s_strd, lsl #1 1786 vmovl.s8 q0, d0 1787 mov \my, \h 1788168: 1789 add \ds2, \dst, \d_strd 1790 add \sr2, \src, \s_strd 1791 lsl \s_strd, \s_strd, #1 1792 lsl \d_strd, \d_strd, #1 1793 1794 load_reg \src, \sr2, \s_strd, d2, d4, d6, d8, d16, d18, d20 1795 vmovl_u8 q1, d2, q2, d4, q3, d6, q4, d8, q8, d16, q9, d18, q10, d20 1796 179788: 1798 subs \h, \h, #2 1799 load_reg \sr2, \src, \s_strd, d22, d24 1800 vmovl_u8 q11, d22, q12, d24 1801 mul_mla_8_1 q1, q2, q1, q2, q3, q4, q8, q9, q10, q11, q12 1802 shift_store_8 \type, \d_strd, q1, d2, q2, d4 1803 ble 9f 1804 subs \h, \h, #2 1805 load_reg \sr2, \src, \s_strd, d26, d28 1806 vmovl_u8 q13, d26, q14, d28 1807 mul_mla_8_1 q3, q4, q3, q4, q8, q9, q10, q11, q12, q13, q14 1808 shift_store_8 \type, \d_strd, q3, d6, q4, d8 1809 ble 9f 1810 subs \h, \h, #2 1811 load_reg \sr2, \src, \s_strd, d30, d2 1812 vmovl_u8 q15, d30, q1, d2 1813 mul_mla_8_1 q8, q9, q8, q9, q10, q11, q12, q13, q14, q15, q1 1814 shift_store_8 \type, \d_strd, q8, d16, q9, d18 1815 ble 9f 1816 subs \h, \h, #2 1817 load_reg \sr2, \src, \s_strd, d4, d6 1818 vmovl_u8 q2, d4, q3, d6 1819 mul_mla_8_1 q10, q11, q10, q11, q12, q13, q14, q15, q1, q2, q3 1820 shift_store_8 \type, \d_strd, q10, d20, q11, d22 1821 ble 9f 1822 subs \h, \h, #4 1823 load_reg \sr2, \src, \s_strd, d8, d16, d18, d20 1824 vmovl_u8 q4, d8, q8, d16, q9, d18, q10, d20 1825 mul_mla_8_1 q12, q13, q12, q13, q14, q15, q1, q2, q3, q4, q8 1826 mul_mla_8_1 q14, q15, q14, q15, q1, q2, q3, q4, q8, q9, q10 1827 shift_store_8 \type, \d_strd, q12, d24, q13, d26, q14, d28, q15, d30 1828 bgt 88b 18299: 1830 subs \w, \w, #8 1831 ble 0f 1832 asr \s_strd, \s_strd, #1 1833 asr \d_strd, \d_strd, #1 1834 mls \src, \s_strd, \my, \src 1835 mls \dst, \d_strd, \my, \dst 1836 sub \src, \src, \s_strd, lsl #3 1837 mov \h, \my 1838 add \src, \src, #8 1839.ifc \type, put 1840 add \dst, \dst, #8 1841.else 1842 add \dst, \dst, #16 1843.endif 1844 b 168b 18450: 1846 vpop {q4} 1847 pop {r4-r11,pc} 1848 1849160: 1850 bgt 1680b 1851 1852 // 16x2, 16x4 v 1853 add \my, \my, #2 1854 vld1.32 {d0[]}, [\my] 1855 sub \src, \src, \s_strd 1856 add \ds2, \dst, \d_strd 1857 add \sr2, \src, \s_strd 1858 lsl \s_strd, \s_strd, #1 1859 lsl \d_strd, \d_strd, #1 1860 vmovl.s8 q0, d0 1861 1862 cmp \h, #2 1863 load_reg \src, \sr2, \s_strd, q11, q12, q13, q14, q15 1864 vmovl.u8 q1, d22 1865 vmovl.u8 q2, d24 1866 vmovl.u8 q3, d26 1867 vmovl.u8 q8, d28 1868 vmovl.u8 q9, d30 1869 vmovl.u8 q11, d23 1870 vmovl.u8 q12, d25 1871 vmovl.u8 q13, d27 1872 vmovl.u8 q14, d29 1873 vmovl.u8 q15, d31 1874 mul_mla_4 q1, q1, q2, q3, q8 1875 mul_mla_4 q10, q2, q3, q8, q9 1876 mul_mla_4 q2, q11, q12, q13, q14 1877 mul_mla_4 q11, q12, q13, q14, q15 1878 shift_store_16 \type, \d_strd, q1, d2, d3, q2, q10, d20, d21, q11 1879 ble 0f 1880 load_reg \sr2, \src, \s_strd, q10, q11 1881 vmovl.u8 q1, d20 1882 vmovl.u8 q10, d21 1883 vmovl.u8 q12, d22 1884 vmovl.u8 q11, d23 1885 mul_mla_4 q2, q3, q8, q9, q1 1886 mul_mla_4 q3, q13, q14, q15, q10 1887 mul_mla_4 q13, q8, q9, q1, q12 1888 mul_mla_4 q14, q14, q15, q10, q11 1889 shift_store_16 \type, \d_strd, q2, d4, d5, q3, q13, d26, d27, q14 18900: 1891 pop {r4-r11,pc} 1892 1893L(\type\()_8tap_hv): 1894 cmp \h, #4 1895 ubfx r9, \my, #7, #7 1896 and \my, \my, #0x7f 1897 it gt 1898 movgt \my, r9 1899 add \my, r10, \my, lsl #3 1900 1901 adr r9, L(\type\()_8tap_hv_tbl) 1902 ldr r8, [r9, r8, lsl #2] 1903 add r9, r9, r8 1904 bx r9 1905 1906 .align 2 1907L(\type\()_8tap_hv_tbl): 1908 .word 1280f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1909 .word 640f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1910 .word 320f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1911 .word 160f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1912 .word 80f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1913 .word 40f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1914 .word 20f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1915 191620: 1917.ifc \type, put 1918 add \mx, \mx, #2 1919 vld1.32 {d0[]}, [\mx] 1920 bgt 280f 1921 add \my, \my, #2 1922 vld1.32 {d2[]}, [\my] 1923 1924 // 2x2, 2x4 hv 1925 sub \sr2, \src, #1 1926 sub \src, \sr2, \s_strd 1927 add \ds2, \dst, \d_strd 1928 lsl \s_strd, \s_strd, #1 1929 lsl \d_strd, \d_strd, #1 1930 vmovl.s8 q0, d0 1931 vmovl.s8 q1, d2 1932 1933 1934 vld1.8 {d26}, [\src], \s_strd 1935 vmovl.u8 q13, d26 1936 vext.8 q14, q13, q13, #2 1937 vmul.s16 d26, d26, d0 1938 vmul.s16 d28, d28, d0 1939 vpadd.s16 d26, d26, d28 1940 vpadd.s16 d26, d26, d26 1941 vrshr.s16 d16, d26, #2 1942 bl L(\type\()_8tap_filter_2) 1943 1944 vext.8 d16, d16, d16, #4 1945 vmov d17, d26 1946 vext.8 d16, d16, d26, #4 1947 19482: 1949 bl L(\type\()_8tap_filter_2) 1950 1951 vext.8 d18, d17, d26, #4 1952 vmull.s16 q2, d16, d2[0] 1953 vmlal.s16 q2, d17, d2[1] 1954 vmlal.s16 q2, d18, d2[2] 1955 vmlal.s16 q2, d26, d2[3] 1956 1957 vqrshrn.s32 d4, q2, #\shift_hv 1958 vqmovun.s16 d4, q2 1959 subs \h, \h, #2 1960 vst1.16 {d4[0]}, [\dst, :16], \d_strd 1961 vst1.16 {d4[1]}, [\ds2, :16], \d_strd 1962 ble 0f 1963 vmov d16, d18 1964 vmov d17, d26 1965 b 2b 1966 1967280: // 2x8, 2x16, 2x32 hv 1968 vld1.8 {d2}, [\my, :64] 1969 sub \src, \src, #1 1970 sub \sr2, \src, \s_strd, lsl #1 1971 sub \src, \sr2, \s_strd 1972 add \ds2, \dst, \d_strd 1973 lsl \s_strd, \s_strd, #1 1974 lsl \d_strd, \d_strd, #1 1975 vmovl.s8 q0, d0 1976 vmovl.s8 q1, d2 1977 1978 vld1.8 {d26}, [\src], \s_strd 1979 vmovl.u8 q13, d26 1980 vext.8 q14, q13, q13, #2 1981 vmul.s16 d26, d26, d0 1982 vmul.s16 d28, d28, d0 1983 vpadd.s16 d26, d26, d28 1984 vpadd.s16 d26, d26, d26 1985 vrshr.s16 d16, d26, #2 1986 1987 bl L(\type\()_8tap_filter_2) 1988 vext.8 d16, d16, d16, #4 1989 vmov d17, d26 1990 vext.8 d16, d16, d26, #4 1991 bl L(\type\()_8tap_filter_2) 1992 vext.8 d18, d17, d26, #4 1993 vmov d19, d26 1994 bl L(\type\()_8tap_filter_2) 1995 vext.8 d20, d19, d26, #4 1996 vmov d21, d26 1997 199828: 1999 bl L(\type\()_8tap_filter_2) 2000 vext.8 d22, d21, d26, #4 2001 vmull.s16 q2, d16, d2[0] 2002 vmlal.s16 q2, d17, d2[1] 2003 vmlal.s16 q2, d18, d2[2] 2004 vmlal.s16 q2, d19, d2[3] 2005 vmlal.s16 q2, d20, d3[0] 2006 vmlal.s16 q2, d21, d3[1] 2007 vmlal.s16 q2, d22, d3[2] 2008 vmlal.s16 q2, d26, d3[3] 2009 2010 vqrshrn.s32 d4, q2, #\shift_hv 2011 vqmovun.s16 d4, q2 2012 subs \h, \h, #2 2013 vst1.16 {d4[0]}, [\dst, :16], \d_strd 2014 vst1.16 {d4[1]}, [\ds2, :16], \d_strd 2015 ble 0f 2016 vmov d16, d18 2017 vmov d17, d19 2018 vmov d18, d20 2019 vmov d19, d21 2020 vmov d20, d22 2021 vmov d21, d26 2022 b 28b 2023 20240: 2025 pop {r4-r11,pc} 2026 2027L(\type\()_8tap_filter_2): 2028 vld1.8 {d28}, [\sr2], \s_strd 2029 vld1.8 {d30}, [\src], \s_strd 2030 vext.8 d29, d28, d28, #1 2031 vext.8 d31, d30, d30, #1 2032 vmovl.u8 q13, d28 2033 vmovl.u8 q14, d29 2034 vmov d27, d28 2035 vmovl.u8 q14, d30 2036 vmovl.u8 q15, d31 2037 vtrn.32 d26, d28 2038 vtrn.32 d27, d30 2039 vmul.s16 d26, d26, d0[0] 2040 vmla.s16 d26, d27, d0[1] 2041 vmla.s16 d26, d28, d0[2] 2042 vmla.s16 d26, d30, d0[3] 2043 vrshr.s16 d26, d26, #2 2044 vext.8 d27, d26, d26, #4 2045 bx lr 2046.endif 2047 204840: 2049 add \mx, \mx, #2 2050 vld1.32 {d0[]}, [\mx] 2051 bgt 480f 2052 add \my, \my, #2 2053 vld1.32 {d2[]}, [\my] 2054 sub \sr2, \src, #1 2055 sub \src, \sr2, \s_strd 2056 add \ds2, \dst, \d_strd 2057 lsl \s_strd, \s_strd, #1 2058 lsl \d_strd, \d_strd, #1 2059 vmovl.s8 q0, d0 2060 vmovl.s8 q1, d2 2061 2062 // 4x2, 4x4 hv 2063 vld1.8 {d30}, [\src], \s_strd 2064 vmovl.u8 q14, d30 2065 vext.8 d27, d28, d29, #2 2066 vext.8 d30, d28, d29, #4 2067 vext.8 d31, d28, d29, #6 2068 vmul.s16 d26, d28, d0[0] 2069 vmla.s16 d26, d27, d0[1] 2070 vmla.s16 d26, d30, d0[2] 2071 vmla.s16 d26, d31, d0[3] 2072 vrshr.s16 d16, d26, #2 2073 2074 bl L(\type\()_8tap_filter_4) 2075 vmov d17, d26 2076 vmov d18, d27 2077 20784: 2079 bl L(\type\()_8tap_filter_4) 2080 vmull.s16 q2, d16, d2[0] 2081 vmlal.s16 q2, d17, d2[1] 2082 vmlal.s16 q2, d18, d2[2] 2083 vmlal.s16 q2, d26, d2[3] 2084 vmull.s16 q3, d17, d2[0] 2085 vmlal.s16 q3, d18, d2[1] 2086 vmlal.s16 q3, d26, d2[2] 2087 vmlal.s16 q3, d27, d2[3] 2088 vqrshrn.s32 d4, q2, #\shift_hv 2089 vqrshrn.s32 d6, q3, #\shift_hv 2090 subs \h, \h, #2 2091.ifc \type, put 2092 vqmovun.s16 d4, q2 2093 vqmovun.s16 d6, q3 2094 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2095 vst1.32 {d6[0]}, [\ds2, :32], \d_strd 2096.else 2097 vst1.16 {d4}, [\dst, :64], \d_strd 2098 vst1.16 {d6}, [\ds2, :64], \d_strd 2099.endif 2100 ble 0f 2101 vmov d16, d18 2102 vmov d17, d26 2103 vmov d18, d27 2104 b 4b 2105 2106480: // 4x8, 4x16, 4x32 hv 2107 vld1.8 {d2}, [\my, :64] 2108 sub \src, \src, #1 2109 sub \sr2, \src, \s_strd, lsl #1 2110 sub \src, \sr2, \s_strd 2111 add \ds2, \dst, \d_strd 2112 lsl \s_strd, \s_strd, #1 2113 lsl \d_strd, \d_strd, #1 2114 vmovl.s8 q0, d0 2115 vmovl.s8 q1, d2 2116 2117 vld1.8 {d30}, [\src], \s_strd 2118 vmovl.u8 q14, d30 2119 vext.8 d27, d28, d29, #2 2120 vext.8 d30, d28, d29, #4 2121 vext.8 d31, d28, d29, #6 2122 vmul.s16 d26, d28, d0[0] 2123 vmla.s16 d26, d27, d0[1] 2124 vmla.s16 d26, d30, d0[2] 2125 vmla.s16 d26, d31, d0[3] 2126 vrshr.s16 d16, d26, #2 2127 2128 bl L(\type\()_8tap_filter_4) 2129 vmov d17, d26 2130 vmov d18, d27 2131 bl L(\type\()_8tap_filter_4) 2132 vmov d19, d26 2133 vmov d20, d27 2134 bl L(\type\()_8tap_filter_4) 2135 vmov d21, d26 2136 vmov d22, d27 2137 213848: 2139 bl L(\type\()_8tap_filter_4) 2140 vmull.s16 q2, d16, d2[0] 2141 vmlal.s16 q2, d17, d2[1] 2142 vmlal.s16 q2, d18, d2[2] 2143 vmlal.s16 q2, d19, d2[3] 2144 vmlal.s16 q2, d20, d3[0] 2145 vmlal.s16 q2, d21, d3[1] 2146 vmlal.s16 q2, d22, d3[2] 2147 vmlal.s16 q2, d26, d3[3] 2148 vmull.s16 q3, d17, d2[0] 2149 vmlal.s16 q3, d18, d2[1] 2150 vmlal.s16 q3, d19, d2[2] 2151 vmlal.s16 q3, d20, d2[3] 2152 vmlal.s16 q3, d21, d3[0] 2153 vmlal.s16 q3, d22, d3[1] 2154 vmlal.s16 q3, d26, d3[2] 2155 vmlal.s16 q3, d27, d3[3] 2156 vqrshrn.s32 d4, q2, #\shift_hv 2157 vqrshrn.s32 d6, q3, #\shift_hv 2158 subs \h, \h, #2 2159.ifc \type, put 2160 vqmovun.s16 d4, q2 2161 vqmovun.s16 d6, q3 2162 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2163 vst1.32 {d6[0]}, [\ds2, :32], \d_strd 2164.else 2165 vst1.16 {d4}, [\dst, :64], \d_strd 2166 vst1.16 {d6}, [\ds2, :64], \d_strd 2167.endif 2168 ble 0f 2169 vmov d16, d18 2170 vmov d17, d19 2171 vmov d18, d20 2172 vmov d19, d21 2173 vmov d20, d22 2174 vmov d21, d26 2175 vmov d22, d27 2176 b 48b 21770: 2178 pop {r4-r11,pc} 2179 2180L(\type\()_8tap_filter_4): 2181 vld1.8 {d30}, [\sr2], \s_strd 2182 vld1.8 {d31}, [\src], \s_strd 2183 vmovl.u8 q14, d30 2184 vext.8 d27, d28, d29, #2 2185 vext.8 d30, d28, d29, #4 2186 vext.8 d1, d28, d29, #6 2187 vmul.s16 d26, d28, d0[0] 2188 vmla.s16 d26, d27, d0[1] 2189 vmla.s16 d26, d30, d0[2] 2190 vmla.s16 d26, d1, d0[3] 2191 2192 vmovl.u8 q14, d31 2193 vext.8 d30, d28, d29, #2 2194 vext.8 d31, d28, d29, #4 2195 vext.8 d1, d28, d29, #6 2196 vmul.s16 d27, d28, d0[0] 2197 vmla.s16 d27, d30, d0[1] 2198 vmla.s16 d27, d31, d0[2] 2199 vmla.s16 d27, d1, d0[3] 2200 vrshr.s16 d26, d26, #2 2201 vrshr.s16 d27, d27, #2 2202 bx lr 2203 220480: 2205160: 2206320: 2207 bgt 880f 2208 vpush {q4-q7} 2209 add \my, \my, #2 2210 vld1.8 {d0}, [\mx, :64] 2211 vld1.32 {d2[]}, [\my] 2212 sub \src, \src, #3 2213 sub \src, \src, \s_strd 2214 vmovl.s8 q0, d0 2215 vmovl.s8 q1, d2 2216 mov \my, \h 2217 2218164: // 8x2, 8x4, 16x2, 16x4, 32x2, 32x4 hv 2219 add \ds2, \dst, \d_strd 2220 add \sr2, \src, \s_strd 2221 lsl \d_strd, \d_strd, #1 2222 lsl \s_strd, \s_strd, #1 2223 2224 vld1.8 {q14}, [\src], \s_strd 2225 vmovl.u8 q12, d28 2226 vmovl.u8 q13, d29 2227 vmul.s16 q10, q12, d0[0] 2228.irpc i, 123 2229 vext.8 q14, q12, q13, #(2*\i) 2230 vmla.s16 q10, q14, d0[\i] 2231.endr 2232.irpc i, 4567 2233 vext.8 q14, q12, q13, #(2*\i) 2234 vmla.s16 q10, q14, d1[\i-4] 2235.endr 2236 vrshr.s16 q3, q10, #2 2237 2238 bl L(\type\()_8tap_filter_8) 2239 vmov q4, q10 2240 vmov q5, q11 2241 22428: 2243 bl L(\type\()_8tap_filter_8) 2244 vmull.s16 q12, d6, d2[0] 2245 vmull.s16 q13, d7, d2[0] 2246 vmull.s16 q14, d8, d2[0] 2247 vmull.s16 q15, d9, d2[0] 2248 vmlal.s16 q12, d8, d2[1] 2249 vmlal.s16 q13, d9, d2[1] 2250 vmlal.s16 q14, d10, d2[1] 2251 vmlal.s16 q15, d11, d2[1] 2252 vmlal.s16 q12, d10, d2[2] 2253 vmlal.s16 q13, d11, d2[2] 2254 vmlal.s16 q14, d20, d2[2] 2255 vmlal.s16 q15, d21, d2[2] 2256 vmlal.s16 q12, d20, d2[3] 2257 vmlal.s16 q13, d21, d2[3] 2258 vmlal.s16 q14, d22, d2[3] 2259 vmlal.s16 q15, d23, d2[3] 2260 vqrshrn.s32 d24, q12, #\shift_hv 2261 vqrshrn.s32 d25, q13, #\shift_hv 2262 vqrshrn.s32 d28, q14, #\shift_hv 2263 vqrshrn.s32 d29, q15, #\shift_hv 2264 subs \h, \h, #2 2265.ifc \type, put 2266 vqmovun.s16 d24, q12 2267 vqmovun.s16 d28, q14 2268 vst1.8 {d24}, [\dst, :64], \d_strd 2269 vst1.8 {d28}, [\ds2, :64], \d_strd 2270.else 2271 vst1.16 {q12}, [\dst, :128], \d_strd 2272 vst1.16 {q14}, [\ds2, :128], \d_strd 2273.endif 2274 ble 9f 2275 vmov q3, q5 2276 vmov q4, q10 2277 vmov q5, q11 2278 b 8b 22799: 2280 subs \w, \w, #8 2281 ble 0f 2282 asr \s_strd, \s_strd, #1 2283 asr \d_strd, \d_strd, #1 2284 mls \src, \s_strd, \my, \src 2285 mls \dst, \d_strd, \my, \dst 2286 sub \src, \src, \s_strd, lsl #2 2287 mov \h, \my 2288 add \src, \src, #8 2289.ifc \type, put 2290 add \dst, \dst, #8 2291.else 2292 add \dst, \dst, #16 2293.endif 2294 b 164b 2295 2296880: // 8x8, 8x16, ..., 16x8, ..., 32x8, ... hv 2297640: 22981280: 2299 vpush {q4-q7} 2300 vld1.8 {d0}, [\mx, :64] 2301 vld1.8 {d2}, [\my, :64] 2302 sub \src, \src, #3 2303 sub \src, \src, \s_strd 2304 sub \src, \src, \s_strd, lsl #1 2305 vmovl.s8 q0, d0 2306 vmovl.s8 q1, d2 2307 mov \my, \h 2308 2309168: 2310 add \ds2, \dst, \d_strd 2311 add \sr2, \src, \s_strd 2312 lsl \d_strd, \d_strd, #1 2313 lsl \s_strd, \s_strd, #1 2314 2315 vld1.8 {q14}, [\src], \s_strd 2316 vmovl.u8 q12, d28 2317 vmovl.u8 q13, d29 2318 vmul.s16 q10, q12, d0[0] 2319.irpc i, 123 2320 vext.8 q14, q12, q13, #(2*\i) 2321 vmla.s16 q10, q14, d0[\i] 2322.endr 2323.irpc i, 4567 2324 vext.8 q14, q12, q13, #(2*\i) 2325 vmla.s16 q10, q14, d1[\i-4] 2326.endr 2327 vrshr.s16 q3, q10, #2 2328 2329 bl L(\type\()_8tap_filter_8) 2330 vmov q4, q10 2331 vmov q5, q11 2332 bl L(\type\()_8tap_filter_8) 2333 vmov q6, q10 2334 vmov q7, q11 2335 bl L(\type\()_8tap_filter_8) 2336 vmov q8, q10 2337 vmov q9, q11 2338 233988: 2340 bl L(\type\()_8tap_filter_8) 2341 vmull.s16 q12, d6, d2[0] 2342 vmull.s16 q13, d7, d2[0] 2343 vmull.s16 q14, d8, d2[0] 2344 vmull.s16 q15, d9, d2[0] 2345 vmlal.s16 q12, d8, d2[1] 2346 vmlal.s16 q13, d9, d2[1] 2347 vmlal.s16 q14, d10, d2[1] 2348 vmlal.s16 q15, d11, d2[1] 2349 vmlal.s16 q12, d10, d2[2] 2350 vmlal.s16 q13, d11, d2[2] 2351 vmlal.s16 q14, d12, d2[2] 2352 vmlal.s16 q15, d13, d2[2] 2353 vmlal.s16 q12, d12, d2[3] 2354 vmlal.s16 q13, d13, d2[3] 2355 vmlal.s16 q14, d14, d2[3] 2356 vmlal.s16 q15, d15, d2[3] 2357 vmlal.s16 q12, d14, d3[0] 2358 vmlal.s16 q13, d15, d3[0] 2359 vmlal.s16 q14, d16, d3[0] 2360 vmlal.s16 q15, d17, d3[0] 2361 vmlal.s16 q12, d16, d3[1] 2362 vmlal.s16 q13, d17, d3[1] 2363 vmlal.s16 q14, d18, d3[1] 2364 vmlal.s16 q15, d19, d3[1] 2365 vmlal.s16 q12, d18, d3[2] 2366 vmlal.s16 q13, d19, d3[2] 2367 vmlal.s16 q14, d20, d3[2] 2368 vmlal.s16 q15, d21, d3[2] 2369 vmlal.s16 q12, d20, d3[3] 2370 vmlal.s16 q13, d21, d3[3] 2371 vmlal.s16 q14, d22, d3[3] 2372 vmlal.s16 q15, d23, d3[3] 2373 vqrshrn.s32 d24, q12, #\shift_hv 2374 vqrshrn.s32 d25, q13, #\shift_hv 2375 vqrshrn.s32 d28, q14, #\shift_hv 2376 vqrshrn.s32 d29, q15, #\shift_hv 2377 subs \h, \h, #2 2378.ifc \type, put 2379 vqmovun.s16 d24, q12 2380 vqmovun.s16 d28, q14 2381 vst1.8 {d24}, [\dst, :64], \d_strd 2382 vst1.8 {d28}, [\ds2, :64], \d_strd 2383.else 2384 vst1.16 {q12}, [\dst, :128], \d_strd 2385 vst1.16 {q14}, [\ds2, :128], \d_strd 2386.endif 2387 ble 9f 2388 vmov q3, q5 2389 vmov q4, q6 2390 vmov q5, q7 2391 vmov q6, q8 2392 vmov q7, q9 2393 vmov q8, q10 2394 vmov q9, q11 2395 b 88b 23969: 2397 subs \w, \w, #8 2398 ble 0f 2399 asr \s_strd, \s_strd, #1 2400 asr \d_strd, \d_strd, #1 2401 mls \src, \s_strd, \my, \src 2402 mls \dst, \d_strd, \my, \dst 2403 sub \src, \src, \s_strd, lsl #3 2404 mov \h, \my 2405 add \src, \src, #8 2406.ifc \type, put 2407 add \dst, \dst, #8 2408.else 2409 add \dst, \dst, #16 2410.endif 2411 b 168b 24120: 2413 vpop {q4-q7} 2414 pop {r4-r11,pc} 2415 2416L(\type\()_8tap_filter_8): 2417 vld1.8 {q14}, [\sr2], \s_strd 2418 vld1.8 {q15}, [\src], \s_strd 2419 vmovl.u8 q12, d28 2420 vmovl.u8 q13, d29 2421 vmul.s16 q10, q12, d0[0] 2422.irpc i, 123 2423 vext.8 q14, q12, q13, #(2*\i) 2424 vmla.s16 q10, q14, d0[\i] 2425.endr 2426.irpc i, 4567 2427 vext.8 q14, q12, q13, #(2*\i) 2428 vmla.s16 q10, q14, d1[\i-4] 2429.endr 2430 vmovl.u8 q12, d30 2431 vmovl.u8 q13, d31 2432 vmul.s16 q11, q12, d0[0] 2433.irpc i, 123 2434 vext.8 q14, q12, q13, #(2*\i) 2435 vmla.s16 q11, q14, d0[\i] 2436.endr 2437.irpc i, 4567 2438 vext.8 q14, q12, q13, #(2*\i) 2439 vmla.s16 q11, q14, d1[\i-4] 2440.endr 2441 vrshr.s16 q10, q10, #2 2442 vrshr.s16 q11, q11, #2 2443 bx lr 2444endfunc 2445 2446 2447function \type\()_bilin_8bpc_neon, export=1 2448 push {r4-r11,lr} 2449 ldrd r4, r5, [sp, #36] 2450 ldrd r6, r7, [sp, #44] 2451 vdup.8 d1, \mx 2452 vdup.8 d3, \my 2453 rsb r8, \mx, #16 2454 rsb r9, \my, #16 2455 vdup.8 d0, r8 2456 vdup.8 d2, r9 2457.ifc \type, prep 2458 lsl \d_strd, \w, #1 2459.endif 2460 clz r8, \w 2461 cmp \mx, #0 2462 sub r8, r8, #24 2463 bne L(\type\()_bilin_h) 2464 cmp \my, #0 2465 bne L(\type\()_bilin_v) 2466 b \type\()_neon 2467 2468L(\type\()_bilin_h): 2469 cmp \my, #0 2470 bne L(\type\()_bilin_hv) 2471 2472 adr r9, L(\type\()_bilin_h_tbl) 2473 ldr r8, [r9, r8, lsl #2] 2474 add r9, r9, r8 2475 bx r9 2476 2477 .align 2 2478L(\type\()_bilin_h_tbl): 2479 .word 1280f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2480 .word 640f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2481 .word 320f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2482 .word 160f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2483 .word 80f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2484 .word 40f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2485 .word 20f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2486 248720: // 2xN h 2488.ifc \type, put 2489 add \ds2, \dst, \d_strd 2490 add \sr2, \src, \s_strd 2491 lsl \d_strd, \d_strd, #1 2492 lsl \s_strd, \s_strd, #1 24932: 2494 vld1.32 {d4[]}, [\src], \s_strd 2495 vld1.32 {d6[]}, [\sr2], \s_strd 2496 vext.8 d5, d4, d4, #1 2497 vext.8 d7, d6, d6, #1 2498 vtrn.16 q2, q3 2499 subs \h, \h, #2 2500 vmull.u8 q3, d4, d0 2501 vmlal.u8 q3, d5, d1 2502 vqrshrn.u16 d4, q3, #4 2503 vst1.16 {d4[0]}, [\dst, :16], \d_strd 2504 vst1.16 {d4[1]}, [\ds2, :16], \d_strd 2505 bgt 2b 2506 pop {r4-r11,pc} 2507.endif 2508 250940: // 4xN h 2510 add \ds2, \dst, \d_strd 2511 add \sr2, \src, \s_strd 2512 lsl \d_strd, \d_strd, #1 2513 lsl \s_strd, \s_strd, #1 25144: 2515 vld1.8 {d4}, [\src], \s_strd 2516 vld1.8 {d6}, [\sr2], \s_strd 2517 vext.8 d5, d4, d4, #1 2518 vext.8 d7, d6, d6, #1 2519 vtrn.32 q2, q3 2520 subs \h, \h, #2 2521 vmull.u8 q3, d4, d0 2522 vmlal.u8 q3, d5, d1 2523.ifc \type, put 2524 vqrshrn.u16 d4, q3, #4 2525 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2526 vst1.32 {d4[1]}, [\ds2, :32], \d_strd 2527.else 2528 vst1.16 {d6}, [\dst, :64], \d_strd 2529 vst1.16 {d7}, [\ds2, :64], \d_strd 2530.endif 2531 bgt 4b 2532 pop {r4-r11,pc} 2533 253480: // 8xN h 2535 add \ds2, \dst, \d_strd 2536 add \sr2, \src, \s_strd 2537 lsl \d_strd, \d_strd, #1 2538 lsl \s_strd, \s_strd, #1 25398: 2540 vld1.8 {q8}, [\src], \s_strd 2541 vld1.8 {q10}, [\sr2], \s_strd 2542 vext.8 q9, q8, q8, #1 2543 vext.8 q11, q10, q10, #1 2544 subs \h, \h, #2 2545 vmull.u8 q8, d16, d0 2546 vmull.u8 q10, d20, d0 2547 vmlal.u8 q8, d18, d1 2548 vmlal.u8 q10, d22, d1 2549.ifc \type, put 2550 vqrshrn.u16 d16, q8, #4 2551 vqrshrn.u16 d18, q10, #4 2552 vst1.8 {d16}, [\dst, :64], \d_strd 2553 vst1.8 {d18}, [\ds2, :64], \d_strd 2554.else 2555 vst1.16 {q8}, [\dst, :128], \d_strd 2556 vst1.16 {q10}, [\ds2, :128], \d_strd 2557.endif 2558 bgt 8b 2559 pop {r4-r11,pc} 2560160: 2561320: 2562640: 25631280: // 16xN, 32xN, ... h 2564 add \ds2, \dst, \d_strd 2565 add \sr2, \src, \s_strd 2566 lsl \s_strd, \s_strd, #1 2567 2568 sub \s_strd, \s_strd, \w 2569 sub \s_strd, \s_strd, #8 2570.ifc \type, put 2571 lsl \d_strd, \d_strd, #1 2572 sub \d_strd, \d_strd, \w 2573.endif 2574161: 2575 vld1.8 {d16}, [\src]! 2576 vld1.8 {d22}, [\sr2]! 2577 mov \mx, \w 2578 257916: 2580 vld1.8 {d17,d18}, [\src]! 2581 vld1.8 {d23,d24}, [\sr2]! 2582 vext.8 q10, q8, q9, #1 2583 vext.8 q13, q11, q12, #1 2584 vmull.u8 q2, d16, d0 2585 vmull.u8 q3, d17, d0 2586 vmull.u8 q14, d22, d0 2587 vmull.u8 q15, d23, d0 2588 vmlal.u8 q2, d20, d1 2589 vmlal.u8 q3, d21, d1 2590 vmlal.u8 q14, d26, d1 2591 vmlal.u8 q15, d27, d1 2592 subs \mx, \mx, #16 2593.ifc \type, put 2594 vqrshrn.u16 d4, q2, #4 2595 vqrshrn.u16 d5, q3, #4 2596 vqrshrn.u16 d28, q14, #4 2597 vqrshrn.u16 d29, q15, #4 2598 vst1.8 {q2}, [\dst, :128]! 2599 vst1.8 {q14}, [\ds2, :128]! 2600.else 2601 vst1.16 {q2, q3}, [\dst, :128]! 2602 vst1.16 {q14, q15}, [\ds2, :128]! 2603.endif 2604 ble 9f 2605 2606 vmov d16, d18 2607 vmov d22, d24 2608 b 16b 2609 26109: 2611 add \dst, \dst, \d_strd 2612 add \ds2, \ds2, \d_strd 2613 add \src, \src, \s_strd 2614 add \sr2, \sr2, \s_strd 2615 2616 subs \h, \h, #2 2617 bgt 161b 2618 pop {r4-r11,pc} 2619 2620L(\type\()_bilin_v): 2621 cmp \h, #4 2622 adr r9, L(\type\()_bilin_v_tbl) 2623 ldr r8, [r9, r8, lsl #2] 2624 add r9, r9, r8 2625 bx r9 2626 2627 .align 2 2628L(\type\()_bilin_v_tbl): 2629 .word 1280f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2630 .word 640f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2631 .word 320f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2632 .word 160f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2633 .word 80f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2634 .word 40f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2635 .word 20f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2636 263720: // 2xN v 2638.ifc \type, put 2639 cmp \h, #2 2640 add \ds2, \dst, \d_strd 2641 add \sr2, \src, \s_strd 2642 lsl \s_strd, \s_strd, #1 2643 lsl \d_strd, \d_strd, #1 2644 2645 // 2x2 v 2646 vld1.16 {d16[]}, [\src], \s_strd 2647 bgt 24f 264822: 2649 vld1.16 {d17[]}, [\sr2], \s_strd 2650 vld1.16 {d18[]}, [\src], \s_strd 2651 vext.8 d16, d16, d17, #6 2652 vext.8 d17, d17, d18, #6 2653 vmull.u8 q2, d16, d2 2654 vmlal.u8 q2, d17, d3 2655 vqrshrn.u16 d4, q2, #4 2656 vst1.16 {d4[0]}, [\dst, :16] 2657 vst1.16 {d4[1]}, [\ds2, :16] 2658 pop {r4-r11,pc} 265924: // 2x4, 2x6, 2x8, ... v 2660 vld1.16 {d17[]}, [\sr2], \s_strd 2661 vld1.16 {d18[]}, [\src], \s_strd 2662 vld1.16 {d19[]}, [\sr2], \s_strd 2663 vld1.16 {d20[]}, [\src], \s_strd 2664 sub \h, \h, #4 2665 vext.8 d16, d16, d17, #6 2666 vext.8 d17, d17, d18, #6 2667 vext.8 d18, d18, d19, #6 2668 vext.8 d19, d19, d20, #6 2669 vtrn.32 d16, d18 2670 vtrn.32 d17, d19 2671 vmull.u8 q2, d16, d2 2672 vmlal.u8 q2, d17, d3 2673 cmp \h, #2 2674 vqrshrn.u16 d4, q2, #4 2675 vst1.16 {d4[0]}, [\dst, :16], \d_strd 2676 vst1.16 {d4[1]}, [\ds2, :16], \d_strd 2677 vst1.16 {d4[2]}, [\dst, :16], \d_strd 2678 vst1.16 {d4[3]}, [\ds2, :16], \d_strd 2679 blt 0f 2680 vmov d16, d20 2681 beq 22b 2682 b 24b 26830: 2684 pop {r4-r11,pc} 2685.endif 2686 268740: // 4xN v 2688 add \ds2, \dst, \d_strd 2689 add \sr2, \src, \s_strd 2690 lsl \s_strd, \s_strd, #1 2691 lsl \d_strd, \d_strd, #1 2692 vld1.32 {d16[]}, [\src], \s_strd 26934: 2694 vld1.32 {d17[]}, [\sr2], \s_strd 2695 vld1.32 {d18[]}, [\src], \s_strd 2696 vext.8 d16, d16, d17, #4 2697 vext.8 d17, d17, d18, #4 2698 vmull.u8 q2, d16, d2 2699 vmlal.u8 q2, d17, d3 2700 subs \h, \h, #2 2701.ifc \type, put 2702 vqrshrn.u16 d4, q2, #4 2703 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2704 vst1.32 {d4[1]}, [\ds2, :32], \d_strd 2705.else 2706 vst1.16 {d4}, [\dst, :64], \d_strd 2707 vst1.16 {d5}, [\ds2, :64], \d_strd 2708.endif 2709 ble 0f 2710 vmov d16, d18 2711 b 4b 27120: 2713 pop {r4-r11,pc} 2714 271580: // 8xN v 2716 add \ds2, \dst, \d_strd 2717 add \sr2, \src, \s_strd 2718 lsl \s_strd, \s_strd, #1 2719 lsl \d_strd, \d_strd, #1 2720 vld1.8 {d16}, [\src], \s_strd 27218: 2722 vld1.8 {d17}, [\sr2], \s_strd 2723 vld1.8 {d18}, [\src], \s_strd 2724 vmull.u8 q2, d16, d2 2725 vmull.u8 q3, d17, d2 2726 vmlal.u8 q2, d17, d3 2727 vmlal.u8 q3, d18, d3 2728 subs \h, \h, #2 2729.ifc \type, put 2730 vqrshrn.u16 d4, q2, #4 2731 vqrshrn.u16 d6, q3, #4 2732 vst1.8 {d4}, [\dst, :64], \d_strd 2733 vst1.8 {d6}, [\ds2, :64], \d_strd 2734.else 2735 vst1.16 {q2}, [\dst, :128], \d_strd 2736 vst1.16 {q3}, [\ds2, :128], \d_strd 2737.endif 2738 ble 0f 2739 vmov d16, d18 2740 b 8b 27410: 2742 pop {r4-r11,pc} 2743 2744160: // 16xN, 32xN, ... 2745320: 2746640: 27471280: 2748 mov \my, \h 27491: 2750 add \ds2, \dst, \d_strd 2751 add \sr2, \src, \s_strd 2752 lsl \s_strd, \s_strd, #1 2753 lsl \d_strd, \d_strd, #1 2754 2755 vld1.8 {q8}, [\src], \s_strd 27562: 2757 vld1.8 {q9}, [\sr2], \s_strd 2758 vld1.8 {q10}, [\src], \s_strd 2759 vmull.u8 q12, d16, d2 2760 vmull.u8 q13, d17, d2 2761 vmull.u8 q14, d18, d2 2762 vmull.u8 q15, d19, d2 2763 vmlal.u8 q12, d18, d3 2764 vmlal.u8 q13, d19, d3 2765 vmlal.u8 q14, d20, d3 2766 vmlal.u8 q15, d21, d3 2767 subs \h, \h, #2 2768.ifc \type, put 2769 vqrshrn.u16 d24, q12, #4 2770 vqrshrn.u16 d25, q13, #4 2771 vqrshrn.u16 d28, q14, #4 2772 vqrshrn.u16 d29, q15, #4 2773 vst1.8 {q12}, [\dst, :128], \d_strd 2774 vst1.8 {q14}, [\ds2, :128], \d_strd 2775.else 2776 vst1.16 {q12, q13}, [\dst, :128], \d_strd 2777 vst1.16 {q14, q15}, [\ds2, :128], \d_strd 2778.endif 2779 ble 9f 2780 vmov q8, q10 2781 b 2b 27829: 2783 subs \w, \w, #16 2784 ble 0f 2785 asr \s_strd, \s_strd, #1 2786 asr \d_strd, \d_strd, #1 2787 mls \src, \s_strd, \my, \src 2788 mls \dst, \d_strd, \my, \dst 2789 sub \src, \src, \s_strd, lsl #1 2790 mov \h, \my 2791 add \src, \src, #16 2792.ifc \type, put 2793 add \dst, \dst, #16 2794.else 2795 add \dst, \dst, #32 2796.endif 2797 b 1b 27980: 2799 pop {r4-r11,pc} 2800 2801L(\type\()_bilin_hv): 2802 vmovl.u8 q2, d2 2803 vmovl.u8 q3, d3 2804 adr r9, L(\type\()_bilin_hv_tbl) 2805 ldr r8, [r9, r8, lsl #2] 2806 add r9, r9, r8 2807 bx r9 2808 2809 .align 2 2810L(\type\()_bilin_hv_tbl): 2811 .word 1280f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2812 .word 640f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2813 .word 320f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2814 .word 160f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2815 .word 80f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2816 .word 40f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2817 .word 20f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2818 281920: // 2xN hv 2820.ifc \type, put 2821 add \sr2, \src, \s_strd 2822 add \ds2, \dst, \d_strd 2823 lsl \s_strd, \s_strd, #1 2824 lsl \d_strd, \d_strd, #1 2825 2826 vld1.32 {d28[]}, [\src], \s_strd 2827 vext.8 d29, d28, d28, #1 2828 vmull.u8 q8, d28, d0 2829 vmlal.u8 q8, d29, d1 2830 28312: 2832 vld1.32 {d28[]}, [\sr2], \s_strd 2833 vld1.32 {d30[]}, [\src], \s_strd 2834 vext.8 d29, d28, d28, #1 2835 vext.8 d31, d30, d30, #1 2836 vtrn.16 d28, d30 2837 vtrn.16 d29, d31 2838 vmull.u8 q9, d28, d0 2839 vmlal.u8 q9, d29, d1 2840 2841 vtrn.32 d16, d18 2842 2843 vmul.u16 d20, d16, d4 2844 vmla.u16 d20, d19, d6 2845 vqrshrn.u16 d20, q10, #8 2846 subs \h, \h, #2 2847 vst1.16 {d20[0]}, [\dst, :16], \d_strd 2848 vst1.16 {d20[1]}, [\ds2, :16], \d_strd 2849 ble 0f 2850 vtrn.32 d19, d16 2851 b 2b 28520: 2853 pop {r4-r11,pc} 2854.endif 2855 285640: // 4xN hv 2857 add \sr2, \src, \s_strd 2858 add \ds2, \dst, \d_strd 2859 lsl \s_strd, \s_strd, #1 2860 lsl \d_strd, \d_strd, #1 2861 2862 vld1.8 {d28}, [\src], \s_strd 2863 vext.8 d29, d28, d28, #1 2864 vmull.u8 q8, d28, d0 2865 vmlal.u8 q8, d29, d1 2866 28674: 2868 vld1.8 {d28}, [\sr2], \s_strd 2869 vld1.8 {d30}, [\src], \s_strd 2870 vext.8 d29, d28, d28, #1 2871 vext.8 d31, d30, d30, #1 2872 vtrn.32 d28, d30 2873 vtrn.32 d29, d31 2874 vmull.u8 q9, d28, d0 2875 vmlal.u8 q9, d29, d1 2876 2877 vmov d17, d18 2878 2879 vmul.u16 q10, q8, q2 2880 vmla.u16 q10, q9, q3 2881 subs \h, \h, #2 2882.ifc \type, put 2883 vqrshrn.u16 d20, q10, #8 2884 vst1.32 {d20[0]}, [\dst, :32], \d_strd 2885 vst1.32 {d20[1]}, [\ds2, :32], \d_strd 2886.else 2887 vrshr.u16 q10, q10, #4 2888 vst1.16 {d20}, [\dst, :64], \d_strd 2889 vst1.16 {d21}, [\ds2, :64], \d_strd 2890.endif 2891 ble 0f 2892 vmov d16, d19 2893 b 4b 28940: 2895 pop {r4-r11,pc} 2896 289780: // 8xN, 16xN, ... hv 2898160: 2899320: 2900640: 29011280: 2902 mov \my, \h 2903 29041: 2905 add \sr2, \src, \s_strd 2906 add \ds2, \dst, \d_strd 2907 lsl \s_strd, \s_strd, #1 2908 lsl \d_strd, \d_strd, #1 2909 2910 vld1.8 {q12}, [\src], \s_strd 2911 vext.8 q13, q12, q12, #1 2912 vmull.u8 q8, d24, d0 2913 vmlal.u8 q8, d26, d1 2914 29152: 2916 vld1.8 {q12}, [\sr2], \s_strd 2917 vld1.8 {q14}, [\src], \s_strd 2918 vext.8 q13, q12, q12, #1 2919 vext.8 q15, q14, q14, #1 2920 vmull.u8 q9, d24, d0 2921 vmlal.u8 q9, d26, d1 2922 vmull.u8 q10, d28, d0 2923 vmlal.u8 q10, d30, d1 2924 2925 vmul.u16 q8, q8, q2 2926 vmla.u16 q8, q9, q3 2927 vmul.u16 q9, q9, q2 2928 vmla.u16 q9, q10, q3 2929 subs \h, \h, #2 2930.ifc \type, put 2931 vqrshrn.u16 d16, q8, #8 2932 vqrshrn.u16 d18, q9, #8 2933 vst1.8 {d16}, [\dst, :64], \d_strd 2934 vst1.8 {d18}, [\ds2, :64], \d_strd 2935.else 2936 vrshr.u16 q8, q8, #4 2937 vrshr.u16 q9, q9, #4 2938 vst1.16 {q8}, [\dst, :128], \d_strd 2939 vst1.16 {q9}, [\ds2, :128], \d_strd 2940.endif 2941 ble 9f 2942 vmov q8, q10 2943 b 2b 29449: 2945 subs \w, \w, #8 2946 ble 0f 2947 asr \s_strd, \s_strd, #1 2948 asr \d_strd, \d_strd, #1 2949 mls \src, \s_strd, \my, \src 2950 mls \dst, \d_strd, \my, \dst 2951 sub \src, \src, \s_strd, lsl #1 2952 mov \h, \my 2953 add \src, \src, #8 2954.ifc \type, put 2955 add \dst, \dst, #8 2956.else 2957 add \dst, \dst, #16 2958.endif 2959 b 1b 29600: 2961 pop {r4-r11,pc} 2962endfunc 2963.endm 2964 2965filter_fn put, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, 10 2966filter_fn prep, r0, r7, r1, r2, r3, r4, r5, r6, r8, r9, 6 2967 2968.macro load_filter_ptr src 2969 asr r12, \src, #10 2970 add r12, r11, r12, lsl #3 2971.endm 2972 2973.macro load_filter_coef dst, src, inc 2974 add \src, \src, \inc 2975 vld1.8 {\dst}, [r12, :64] 2976.endm 2977 2978.macro load_filter_row dst, src, inc 2979 load_filter_ptr \src 2980 load_filter_coef \dst, \src, \inc 2981.endm 2982 2983function warp_filter_horz_neon 2984 load_filter_ptr r5 // filter 0 2985 vld1.16 {q7}, [r2], r3 2986 vmov.i8 q6, #128 2987 2988 load_filter_coef d0, r5, r7 // filter 0 2989 load_filter_row d1, r5, r7 // filter 1 2990 load_filter_row d2, r5, r7 // filter 2 2991 load_filter_ptr r5 // filter 3 2992 veor q7, q7, q6 // subtract by 128 to allow using vmull 2993 load_filter_coef d3, r5, r7 // filter 3 2994 vext.8 d12, d14, d15, #1 // filter 1 pixels 2995 vext.8 d13, d14, d15, #2 // filter 2 pixels 2996 load_filter_ptr r5 // filter 4 2997 vmull.s8 q2, d14, d0 // filter 0 output 2998 vmull.s8 q3, d12, d1 // filter 1 output 2999 load_filter_coef d0, r5, r7 // filter 4 3000 load_filter_ptr r5 // filter 5 3001 vext.8 d12, d14, d15, #3 // filter 3 pixels 3002 vmull.s8 q4, d13, d2 // filter 2 output 3003 vext.8 d13, d14, d15, #4 // filter 4 pixels 3004 vpadd.i16 d4, d4, d5 // pixel 0 (4x16) 3005 vpadd.i16 d5, d6, d7 // pixel 1 (4x16) 3006 load_filter_coef d1, r5, r7 // filter 5 3007 load_filter_ptr r5 // filter 6 3008 vmull.s8 q5, d12, d3 // filter 3 output 3009 vext.8 d12, d14, d15, #5 // filter 5 pixels 3010 vmull.s8 q3, d13, d0 // filter 4 output 3011 load_filter_coef d0, r5, r7 // filter 6 3012 vext.8 d13, d14, d15, #6 // filter 6 pixels 3013 load_filter_ptr r5 // filter 7 3014 vpadd.i16 d8, d8, d9 // pixel 2 (4x16) 3015 vpadd.i16 d9, d10, d11 // pixel 3 (4x16) 3016 vmull.s8 q5, d12, d1 // filter 5 output 3017 load_filter_coef d1, r5, r7 // filter 7 3018 vext.8 d14, d14, d15, #7 // filter 7 pixels 3019 vpadd.i16 d6, d6, d7 // pixel 4 (4x16) 3020 vpadd.i16 d10, d10, d11 // pixel 5 (4x16) 3021 vmull.s8 q6, d13, d0 // filter 6 output 3022 vmull.s8 q7, d14, d1 // filter 7 output 3023 3024 sub r5, r5, r7, lsl #3 3025 3026 vpadd.i16 d4, d4, d5 // pixel 0,1 (2x16) 3027 vpadd.i16 d5, d8, d9 // pixel 2,3 (2x16) 3028 vpadd.i16 d12, d12, d13 // pixel 6 (4x16) 3029 vpadd.i16 d14, d14, d15 // pixel 7 (4x16) 3030 vpadd.i16 d6, d6, d10 // pixel 4,5 (2x16) 3031 vpadd.i16 d10, d12, d14 // pixel 6,7 (2x16) 3032 vpadd.i16 d4, d4, d5 // pixel 0-3 3033 vpadd.i16 d5, d6, d10 // pixel 4-7 3034 3035 add r5, r5, r8 3036 3037 bx lr 3038endfunc 3039 3040// void dav1d_warp_affine_8x8_8bpc_neon( 3041// pixel *dst, const ptrdiff_t dst_stride, 3042// const pixel *src, const ptrdiff_t src_stride, 3043// const int16_t *const abcd, int mx, int my) 3044.macro warp t, shift 3045function warp_affine_8x8\t\()_8bpc_neon, export=1 3046 push {r4-r11,lr} 3047 vpush {q4-q7} 3048 ldrd r4, r5, [sp, #100] 3049 ldr r6, [sp, #108] 3050 ldrd r8, r9, [r4] 3051 sxth r7, r8 3052 asr r8, r8, #16 3053 asr r4, r9, #16 3054 sxth r9, r9 3055 mov r10, #8 3056 sub r2, r2, r3, lsl #1 3057 sub r2, r2, r3 3058 sub r2, r2, #3 3059 movrel r11, X(mc_warp_filter), 64*8 3060.ifnb \t 3061 lsl r1, r1, #1 3062.endif 3063 add r5, r5, #512 3064 add r6, r6, #512 3065 3066 bl warp_filter_horz_neon 3067 vrshr.s16 q8, q2, #3 3068 bl warp_filter_horz_neon 3069 vrshr.s16 q9, q2, #3 3070 bl warp_filter_horz_neon 3071 vrshr.s16 q10, q2, #3 3072 bl warp_filter_horz_neon 3073 vrshr.s16 q11, q2, #3 3074 bl warp_filter_horz_neon 3075 vrshr.s16 q12, q2, #3 3076 bl warp_filter_horz_neon 3077 vrshr.s16 q13, q2, #3 3078 bl warp_filter_horz_neon 3079 vrshr.s16 q14, q2, #3 3080 30811: 3082 bl warp_filter_horz_neon 3083 vrshr.s16 q15, q2, #3 3084 3085 load_filter_row d8, r6, r9 3086 load_filter_row d9, r6, r9 3087 load_filter_row d10, r6, r9 3088 load_filter_row d11, r6, r9 3089 load_filter_row d12, r6, r9 3090 load_filter_row d13, r6, r9 3091 load_filter_row d14, r6, r9 3092 load_filter_row d15, r6, r9 3093 transpose_8x8b q4, q5, q6, q7, d8, d9, d10, d11, d12, d13, d14, d15 3094 vmovl.s8 q1, d8 3095 vmovl.s8 q2, d9 3096 vmovl.s8 q3, d10 3097 vmovl.s8 q4, d11 3098 vmovl.s8 q5, d12 3099 vmovl.s8 q6, d13 3100 3101 sub r6, r6, r9, lsl #3 3102 3103 // This ordering of vmull/vmlal is highly beneficial for 3104 // Cortex A8/A9/A53 here, but harmful for Cortex A7. 3105 vmull.s16 q0, d16, d2 3106 vmlal.s16 q0, d18, d4 3107 vmlal.s16 q0, d20, d6 3108 vmlal.s16 q0, d22, d8 3109 vmlal.s16 q0, d24, d10 3110 vmlal.s16 q0, d26, d12 3111 vmull.s16 q1, d17, d3 3112 vmlal.s16 q1, d19, d5 3113 vmlal.s16 q1, d21, d7 3114 vmlal.s16 q1, d23, d9 3115 vmlal.s16 q1, d25, d11 3116 vmlal.s16 q1, d27, d13 3117 3118 vmovl.s8 q2, d14 3119 vmovl.s8 q3, d15 3120 3121 vmlal.s16 q0, d28, d4 3122 vmlal.s16 q0, d30, d6 3123 vmlal.s16 q1, d29, d5 3124 vmlal.s16 q1, d31, d7 3125 3126.ifb \t 3127 vmov.i16 q7, #128 3128.else 3129 vmov.i16 q7, #0x800 3130.endif 3131 3132 vmov q8, q9 3133 vmov q9, q10 3134 vqrshrn.s32 d0, q0, #\shift 3135 vmov q10, q11 3136 vqrshrn.s32 d1, q1, #\shift 3137 vmov q11, q12 3138 vadd.i16 q0, q0, q7 3139 vmov q12, q13 3140.ifb \t 3141 vqmovun.s16 d0, q0 3142.endif 3143 vmov q13, q14 3144 vmov q14, q15 3145 subs r10, r10, #1 3146.ifnb \t 3147 vst1.16 {q0}, [r0, :128], r1 3148.else 3149 vst1.8 {d0}, [r0, :64], r1 3150.endif 3151 3152 add r6, r6, r4 3153 bgt 1b 3154 3155 vpop {q4-q7} 3156 pop {r4-r11,pc} 3157endfunc 3158.endm 3159 3160warp , 11 3161warp t, 7 3162 3163// void dav1d_emu_edge_8bpc_neon( 3164// const intptr_t bw, const intptr_t bh, 3165// const intptr_t iw, const intptr_t ih, 3166// const intptr_t x, const intptr_t y, 3167// pixel *dst, const ptrdiff_t dst_stride, 3168// const pixel *ref, const ptrdiff_t ref_stride) 3169function emu_edge_8bpc_neon, export=1 3170 push {r4-r11,lr} 3171 ldrd r4, r5, [sp, #36] 3172 ldrd r6, r7, [sp, #44] 3173 ldrd r8, r9, [sp, #52] 3174 3175 // ref += iclip(y, 0, ih - 1) * PXSTRIDE(ref_stride) 3176 // ref += iclip(x, 0, iw - 1) 3177 sub r12, r3, #1 // ih - 1 3178 cmp r5, r3 3179 sub lr, r2, #1 // iw - 1 3180 it lt 3181 movlt r12, r5 // min(y, ih - 1) 3182 cmp r4, r2 3183 bic r12, r12, r12, asr #31 // max(min(y, ih - 1), 0) 3184 it lt 3185 movlt lr, r4 // min(x, iw - 1) 3186 bic lr, lr, lr, asr #31 // max(min(x, iw - 1), 0) 3187 mla r8, r12, r9, r8 // ref += iclip() * stride 3188 add r8, r8, lr // ref += iclip() 3189 3190 // bottom_ext = iclip(y + bh - ih, 0, bh - 1) 3191 // top_ext = iclip(-y, 0, bh - 1) 3192 add r10, r5, r1 // y + bh 3193 neg r5, r5 // -y 3194 sub r10, r10, r3 // y + bh - ih 3195 sub r12, r1, #1 // bh - 1 3196 cmp r10, r1 3197 bic r5, r5, r5, asr #31 // max(-y, 0) 3198 it ge 3199 movge r10, r12 // min(y + bh - ih, bh-1) 3200 cmp r5, r1 3201 bic r10, r10, r10, asr #31 // max(min(y + bh - ih, bh-1), 0) 3202 it ge 3203 movge r5, r12 // min(max(-y, 0), bh-1) 3204 3205 // right_ext = iclip(x + bw - iw, 0, bw - 1) 3206 // left_ext = iclip(-x, 0, bw - 1) 3207 add r11, r4, r0 // x + bw 3208 neg r4, r4 // -x 3209 sub r11, r11, r2 // x + bw - iw 3210 sub lr, r0, #1 // bw - 1 3211 cmp r11, r0 3212 bic r4, r4, r4, asr #31 // max(-x, 0) 3213 it ge 3214 movge r11, lr // min(x + bw - iw, bw-1) 3215 cmp r4, r0 3216 bic r11, r11, r11, asr #31 // max(min(x + bw - iw, bw-1), 0) 3217 it ge 3218 movge r4, lr // min(max(-x, 0), bw - 1) 3219 3220 // center_h = bh - top_ext - bottom_ext 3221 // dst += top_ext * PXSTRIDE(dst_stride) 3222 // center_w = bw - left_ext - right_ext 3223 sub r1, r1, r5 // bh - top_ext 3224 mla r6, r5, r7, r6 3225 sub r2, r0, r4 // bw - left_ext 3226 sub r1, r1, r10 // center_h = bh - top_ext - bottom_ext 3227 sub r2, r2, r11 // center_w = bw - left_ext - right_ext 3228 3229 mov r0, r6 // backup of dst 3230 3231.macro v_loop need_left, need_right 32320: 3233.if \need_left 3234 vld1.8 {d0[], d1[]}, [r8] 3235 mov r12, r6 // out = dst 3236 mov r3, r4 32371: 3238 subs r3, r3, #16 3239 vst1.8 {q0}, [r12, :128]! 3240 bgt 1b 3241.endif 3242 mov lr, r8 3243 add r12, r6, r4 // out = dst + left_ext 3244 mov r3, r2 32451: 3246 vld1.8 {q0, q1}, [lr]! 3247 subs r3, r3, #32 3248.if \need_left 3249 vst1.8 {q0, q1}, [r12]! 3250.else 3251 vst1.8 {q0, q1}, [r12, :128]! 3252.endif 3253 bgt 1b 3254.if \need_right 3255 add r3, r8, r2 // in + center_w 3256 sub r3, r3, #1 // in + center_w - 1 3257 add r12, r6, r4 // dst + left_ext 3258 vld1.8 {d0[], d1[]}, [r3] 3259 add r12, r12, r2 // out = dst + left_ext + center_w 3260 mov r3, r11 32611: 3262 subs r3, r3, #16 3263 vst1.8 {q0}, [r12]! 3264 bgt 1b 3265.endif 3266 3267 subs r1, r1, #1 // center_h-- 3268 add r6, r6, r7 3269 add r8, r8, r9 3270 bgt 0b 3271.endm 3272 3273 cmp r4, #0 3274 beq 2f 3275 // need_left 3276 cmp r11, #0 3277 beq 3f 3278 // need_left + need_right 3279 v_loop 1, 1 3280 b 5f 3281 32822: 3283 // !need_left 3284 cmp r11, #0 3285 beq 4f 3286 // !need_left + need_right 3287 v_loop 0, 1 3288 b 5f 3289 32903: 3291 // need_left + !need_right 3292 v_loop 1, 0 3293 b 5f 3294 32954: 3296 // !need_left + !need_right 3297 v_loop 0, 0 3298 32995: 3300 cmp r10, #0 3301 // Storing the original dst in r0 overwrote bw, recalculate it here 3302 add r2, r2, r4 // center_w + left_ext 3303 add r2, r2, r11 // bw = center_w + left_ext + right_ext 3304 3305 beq 3f 3306 // need_bottom 3307 sub r8, r6, r7 // ref = dst - stride 3308 mov r4, r2 33091: 3310 vld1.8 {q0, q1}, [r8, :128]! 3311 mov r3, r10 33122: 3313 subs r3, r3, #1 3314 vst1.8 {q0, q1}, [r6, :128], r7 3315 bgt 2b 3316 mls r6, r7, r10, r6 // dst -= bottom_ext * stride 3317 subs r4, r4, #32 // bw -= 32 3318 add r6, r6, #32 // dst += 32 3319 bgt 1b 3320 33213: 3322 cmp r5, #0 3323 beq 3f 3324 // need_top 3325 mls r6, r7, r5, r0 // dst = stored_dst - top_ext * stride 33261: 3327 vld1.8 {q0, q1}, [r0, :128]! 3328 mov r3, r5 33292: 3330 subs r3, r3, #1 3331 vst1.8 {q0, q1}, [r6, :128], r7 3332 bgt 2b 3333 mls r6, r7, r5, r6 // dst -= top_ext * stride 3334 subs r2, r2, #32 // bw -= 32 3335 add r6, r6, #32 // dst += 32 3336 bgt 1b 3337 33383: 3339 pop {r4-r11,pc} 3340endfunc 3341