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_1 d0, d1, s0, s1, s2, s3, s4, s5, s6, s7, s8 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 vmul.s16 \d1, \s1, d0[0] 1159 vmla.s16 \d1, \s2, d0[1] 1160 vmla.s16 \d1, \s3, d0[2] 1161 vmla.s16 \d1, \s4, d0[3] 1162 vmla.s16 \d1, \s5, d1[0] 1163 vmla.s16 \d1, \s6, d1[1] 1164 vmla.s16 \d1, \s7, d1[2] 1165 vmla.s16 \d1, \s8, d1[3] 1166.endm 1167.macro mul_mla_8_2 d0, d1, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9 1168 vmul.s16 \d0, \s0, d0[0] 1169 vmla.s16 \d0, \s1, d0[1] 1170 vmla.s16 \d0, \s2, d0[2] 1171 vmla.s16 \d0, \s3, d0[3] 1172 vmla.s16 \d0, \s4, d1[0] 1173 vmla.s16 \d0, \s5, d1[1] 1174 vmla.s16 \d0, \s6, d1[2] 1175 vmla.s16 \d0, \s7, d1[3] 1176 vmul.s16 \d1, \s2, d0[0] 1177 vmla.s16 \d1, \s3, d0[1] 1178 vmla.s16 \d1, \s4, d0[2] 1179 vmla.s16 \d1, \s5, d0[3] 1180 vmla.s16 \d1, \s6, d1[0] 1181 vmla.s16 \d1, \s7, d1[1] 1182 vmla.s16 \d1, \s8, d1[2] 1183 vmla.s16 \d1, \s9, d1[3] 1184.endm 1185.macro mul_mla_8_4 d0, d1, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11 1186 vmul.s16 \d0, \s0, d0[0] 1187 vmla.s16 \d0, \s1, d0[1] 1188 vmla.s16 \d0, \s2, d0[2] 1189 vmla.s16 \d0, \s3, d0[3] 1190 vmla.s16 \d0, \s4, d1[0] 1191 vmla.s16 \d0, \s5, d1[1] 1192 vmla.s16 \d0, \s6, d1[2] 1193 vmla.s16 \d0, \s7, d1[3] 1194 vmul.s16 \d1, \s4, d0[0] 1195 vmla.s16 \d1, \s5, d0[1] 1196 vmla.s16 \d1, \s6, d0[2] 1197 vmla.s16 \d1, \s7, d0[3] 1198 vmla.s16 \d1, \s8, d1[0] 1199 vmla.s16 \d1, \s9, d1[1] 1200 vmla.s16 \d1, \s10, d1[2] 1201 vmla.s16 \d1, \s11, d1[3] 1202.endm 1203.macro vqrshrun_s16 shift, q0, d0, q1, d1, q2, d2, q3, d3 1204 vqrshrun.s16 \d0, \q0, #\shift 1205.ifnb \q1 1206 vqrshrun.s16 \d1, \q1, #\shift 1207.endif 1208.ifnb \q2 1209 vqrshrun.s16 \d2, \q2, #\shift 1210 vqrshrun.s16 \d3, \q3, #\shift 1211.endif 1212.endm 1213.macro vrshr_s16 shift, r0, r1, r2, r3 1214 vrshr.s16 \r0, \r0, #\shift 1215.ifnb \r1 1216 vrshr.s16 \r1, \r1, #\shift 1217.endif 1218.ifnb \r2 1219 vrshr.s16 \r2, \r2, #\shift 1220 vrshr.s16 \r3, \r3, #\shift 1221.endif 1222.endm 1223.macro st_16 strd, reg, lanes 1224 vst1.16 {\reg[0]}, [r0, :16], \strd 1225 vst1.16 {\reg[1]}, [r8, :16], \strd 1226.if \lanes > 2 1227 vst1.16 {\reg[2]}, [r0, :16], \strd 1228 vst1.16 {\reg[3]}, [r8, :16], \strd 1229.endif 1230.endm 1231.macro st_32 strd, r0, r1 1232 vst1.32 {\r0[0]}, [r0, :32], \strd 1233 vst1.32 {\r0[1]}, [r8, :32], \strd 1234.ifnb \r1 1235 vst1.32 {\r1[0]}, [r0, :32], \strd 1236 vst1.32 {\r1[1]}, [r8, :32], \strd 1237.endif 1238.endm 1239.macro st_reg strd, align, r0, r1, r2, r3, r4, r5, r6, r7 1240 vst1.8 {\r0}, [r0, \align], \strd 1241 vst1.8 {\r1}, [r8, \align], \strd 1242.ifnb \r2 1243 vst1.8 {\r2}, [r0, \align], \strd 1244 vst1.8 {\r3}, [r8, \align], \strd 1245.endif 1246.ifnb \r4 1247 vst1.8 {\r4}, [r0, \align], \strd 1248 vst1.8 {\r5}, [r8, \align], \strd 1249 vst1.8 {\r6}, [r0, \align], \strd 1250 vst1.8 {\r7}, [r8, \align], \strd 1251.endif 1252.endm 1253.macro shift_store_4 type, strd, q0, d0, d1, q1, d2, d3 1254.ifc \type, put 1255 vqrshrun_s16 6, \q0, \d0, \q1, \d2 1256 st_32 \strd, \d0, \d2 1257.else 1258 vrshr_s16 2, \q0, \q1 1259 st_reg \strd, :64, \d0, \d1, \d2, \d3 1260.endif 1261.endm 1262.macro shift_store_8 type, strd, q0, d0, q1, d1, q2, d2, q3, d3 1263.ifc \type, put 1264 vqrshrun_s16 6, \q0, \d0, \q1, \d1, \q2, \d2, \q3, \d3 1265 st_reg \strd, :64, \d0, \d1, \d2, \d3 1266.else 1267 vrshr_s16 2, \q0, \q1, \q2, \q3 1268 st_reg \strd, :128,\q0, \q1, \q2, \q3 1269.endif 1270.endm 1271.macro shift_store_16 type, strd, q0, d0, d1, q1, q2, d4, d5, q3 1272.ifc \type, put 1273 vqrshrun.s16 \d0, \q0, #6 1274 vqrshrun.s16 \d1, \q1, #6 1275 vqrshrun.s16 \d4, \q2, #6 1276 vqrshrun.s16 \d5, \q3, #6 1277 st_reg \strd, :128, \q0, \q2 1278.else 1279 vrshr_s16 2, \q0, \q1, \q2, \q3 1280 vst1.16 {\q0, \q1}, [r0, :128], \strd 1281 vst1.16 {\q2, \q3}, [r8, :128], \strd 1282.endif 1283.endm 1284 1285.macro make_8tap_fn op, type, type_h, type_v 1286function \op\()_8tap_\type\()_8bpc_neon, export=1 1287 push {r4-r11,lr} 1288 movw r8, \type_h 1289 movw r9, \type_v 1290 b \op\()_8tap_neon 1291endfunc 1292.endm 1293 1294// No spaces in these expressions, due to gas-preprocessor. 1295#define REGULAR ((0*15<<7)|3*15) 1296#define SMOOTH ((1*15<<7)|4*15) 1297#define SHARP ((2*15<<7)|3*15) 1298 1299.macro filter_fn type, dst, d_strd, src, s_strd, w, h, mx, my, ds2, sr2, shift_hv 1300make_8tap_fn \type, regular, REGULAR, REGULAR 1301make_8tap_fn \type, regular_smooth, REGULAR, SMOOTH 1302make_8tap_fn \type, regular_sharp, REGULAR, SHARP 1303make_8tap_fn \type, smooth, SMOOTH, SMOOTH 1304make_8tap_fn \type, smooth_regular, SMOOTH, REGULAR 1305make_8tap_fn \type, smooth_sharp, SMOOTH, SHARP 1306make_8tap_fn \type, sharp, SHARP, SHARP 1307make_8tap_fn \type, sharp_regular, SHARP, REGULAR 1308make_8tap_fn \type, sharp_smooth, SHARP, SMOOTH 1309 1310function \type\()_8tap_neon 1311 ldrd r4, r5, [sp, #36] 1312 ldrd r6, r7, [sp, #44] 1313 movw r10, #0x4081 // (1 << 14) | (1 << 7) | (1 << 0) 1314 mul \mx, \mx, r10 1315 mul \my, \my, r10 1316 add \mx, \mx, r8 // mx, 8tap_h, 4tap_h 1317 add \my, \my, r9 // my, 8tap_v, 4tap_v 1318.ifc \type, prep 1319 lsl \d_strd, \w, #1 1320.endif 1321 1322 clz r8, \w 1323 tst \mx, #(0x7f << 14) 1324 sub r8, r8, #24 1325 movrel r10, X(mc_subpel_filters), -8 1326 bne L(\type\()_8tap_h) 1327 tst \my, #(0x7f << 14) 1328 bne L(\type\()_8tap_v) 1329 b \type\()_neon 1330 1331L(\type\()_8tap_h): 1332 cmp \w, #4 1333 ubfx r9, \mx, #7, #7 1334 and \mx, \mx, #0x7f 1335 it gt 1336 movgt \mx, r9 1337 tst \my, #(0x7f << 14) 1338 add \mx, r10, \mx, lsl #3 1339 bne L(\type\()_8tap_hv) 1340 1341 adr r9, L(\type\()_8tap_h_tbl) 1342 ldr r8, [r9, r8, lsl #2] 1343 add r9, r9, r8 1344 bx r9 1345 1346 .align 2 1347L(\type\()_8tap_h_tbl): 1348 .word 1280f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1349 .word 640f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1350 .word 320f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1351 .word 160f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1352 .word 80f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1353 .word 40f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1354 .word 20f - L(\type\()_8tap_h_tbl) + CONFIG_THUMB 1355 135620: // 2xN h 1357.ifc \type, put 1358 add \mx, \mx, #2 1359 vld1.32 {d0[]}, [\mx] 1360 sub \src, \src, #1 1361 add \ds2, \dst, \d_strd 1362 add \sr2, \src, \s_strd 1363 lsl \d_strd, \d_strd, #1 1364 lsl \s_strd, \s_strd, #1 1365 vmovl.s8 q0, d0 13662: 1367 vld1.8 {d4}, [\src], \s_strd 1368 vld1.8 {d6}, [\sr2], \s_strd 1369 vmovl.u8 q2, d4 1370 vmovl.u8 q3, d6 1371 vext.8 d5, d4, d5, #2 1372 vext.8 d7, d6, d7, #2 1373 subs \h, \h, #2 1374 vtrn.32 d4, d6 1375 vtrn.32 d5, d7 1376 vmul.s16 d2, d4, d0[0] 1377 vmla.s16 d2, d5, d0[1] 1378 vmla.s16 d2, d6, d0[2] 1379 vmla.s16 d2, d7, d0[3] 1380 vrshr.s16 d2, d2, #2 1381 vqrshrun.s16 d2, q1, #4 1382 vst1.16 {d2[0]}, [\dst, :16], \d_strd 1383 vst1.16 {d2[1]}, [\ds2, :16], \d_strd 1384 bgt 2b 1385 pop {r4-r11,pc} 1386.endif 1387 138840: // 4xN h 1389 add \mx, \mx, #2 1390 vld1.32 {d0[]}, [\mx] 1391 sub \src, \src, #1 1392 add \ds2, \dst, \d_strd 1393 add \sr2, \src, \s_strd 1394 lsl \d_strd, \d_strd, #1 1395 lsl \s_strd, \s_strd, #1 1396 vmovl.s8 q0, d0 13974: 1398 vld1.8 {d16}, [\src], \s_strd 1399 vld1.8 {d24}, [\sr2], \s_strd 1400 vmovl.u8 q8, d16 1401 vmovl.u8 q12, d24 1402 vext.8 d18, d16, d17, #2 1403 vext.8 d20, d16, d17, #4 1404 vext.8 d22, d16, d17, #6 1405 vext.8 d26, d24, d25, #2 1406 vext.8 d28, d24, d25, #4 1407 vext.8 d30, d24, d25, #6 1408 subs \h, \h, #2 1409 vmul.s16 d4, d16, d0[0] 1410 vmla.s16 d4, d18, d0[1] 1411 vmla.s16 d4, d20, d0[2] 1412 vmla.s16 d4, d22, d0[3] 1413 vmul.s16 d5, d24, d0[0] 1414 vmla.s16 d5, d26, d0[1] 1415 vmla.s16 d5, d28, d0[2] 1416 vmla.s16 d5, d30, d0[3] 1417 vrshr.s16 q2, q2, #2 1418.ifc \type, put 1419 vqrshrun.s16 d4, q2, #4 1420 vst1.32 {d4[0]}, [\dst, :32], \d_strd 1421 vst1.32 {d4[1]}, [\ds2, :32], \d_strd 1422.else 1423 vst1.16 {d4}, [\dst, :64], \d_strd 1424 vst1.16 {d5}, [\ds2, :64], \d_strd 1425.endif 1426 bgt 4b 1427 pop {r4-r11,pc} 1428 142980: // 8xN h 1430 vld1.8 {d0}, [\mx, :64] 1431 sub \src, \src, #3 1432 add \ds2, \dst, \d_strd 1433 add \sr2, \src, \s_strd 1434 lsl \d_strd, \d_strd, #1 1435 lsl \s_strd, \s_strd, #1 1436 vmovl.s8 q0, d0 14378: 1438 vld1.8 {q8}, [\src], \s_strd 1439 vld1.8 {q12}, [\sr2], \s_strd 1440 vmovl.u8 q9, d17 1441 vmovl.u8 q8, d16 1442 vmovl.u8 q13, d25 1443 vmovl.u8 q12, d24 1444 1445 vmul.s16 q10, q8, d0[0] 1446 vmul.s16 q14, q12, d0[0] 1447.irpc i, 1234567 1448 vext.8 q11, q8, q9, #(2*\i) 1449 vext.8 q15, q12, q13, #(2*\i) 1450.if \i < 4 1451 vmla.s16 q10, q11, d0[\i] 1452 vmla.s16 q14, q15, d0[\i] 1453.else 1454 vmla.s16 q10, q11, d1[\i-4] 1455 vmla.s16 q14, q15, d1[\i-4] 1456.endif 1457.endr 1458 subs \h, \h, #2 1459 vrshr.s16 q10, q10, #2 1460 vrshr.s16 q14, q14, #2 1461.ifc \type, put 1462 vqrshrun.s16 d20, q10, #4 1463 vqrshrun.s16 d28, q14, #4 1464 vst1.8 {d20}, [\dst, :64], \d_strd 1465 vst1.8 {d28}, [\ds2, :64], \d_strd 1466.else 1467 vst1.16 {q10}, [\dst, :128], \d_strd 1468 vst1.16 {q14}, [\ds2, :128], \d_strd 1469.endif 1470 bgt 8b 1471 pop {r4-r11,pc} 1472 1473160: 1474320: 1475640: 14761280: // 16xN, 32xN, ... h 1477 // This could be done without touching q4-q6, by using only 1478 // one temporary for vext in the loop. That's slower on A7 and A53, 1479 // (but surprisingly, marginally faster on A8 and A73). 1480 vpush {q4-q6} 1481 vld1.8 {d0}, [\mx, :64] 1482 sub \src, \src, #3 1483 add \ds2, \dst, \d_strd 1484 add \sr2, \src, \s_strd 1485 lsl \s_strd, \s_strd, #1 1486 vmovl.s8 q0, d0 1487 1488 sub \s_strd, \s_strd, \w 1489 sub \s_strd, \s_strd, #8 1490.ifc \type, put 1491 lsl \d_strd, \d_strd, #1 1492 sub \d_strd, \d_strd, \w 1493.endif 1494161: 1495 vld1.8 {d16, d17, d18}, [\src]! 1496 vld1.8 {d24, d25, d26}, [\sr2]! 1497 mov \mx, \w 1498 vmovl.u8 q10, d18 1499 vmovl.u8 q9, d17 1500 vmovl.u8 q8, d16 1501 vmovl.u8 q14, d26 1502 vmovl.u8 q13, d25 1503 vmovl.u8 q12, d24 1504 150516: 1506 vmul.s16 q1, q8, d0[0] 1507 vmul.s16 q2, q9, d0[0] 1508 vmul.s16 q3, q12, d0[0] 1509 vmul.s16 q4, q13, d0[0] 1510.irpc i, 1234567 1511 vext.8 q5, q8, q9, #(2*\i) 1512 vext.8 q6, q9, q10, #(2*\i) 1513 vext.8 q11, q12, q13, #(2*\i) 1514 vext.8 q15, q13, q14, #(2*\i) 1515.if \i < 4 1516 vmla.s16 q1, q5, d0[\i] 1517 vmla.s16 q2, q6, d0[\i] 1518 vmla.s16 q3, q11, d0[\i] 1519 vmla.s16 q4, q15, d0[\i] 1520.else 1521 vmla.s16 q1, q5, d1[\i-4] 1522 vmla.s16 q2, q6, d1[\i-4] 1523 vmla.s16 q3, q11, d1[\i-4] 1524 vmla.s16 q4, q15, d1[\i-4] 1525.endif 1526.endr 1527 vrshr.s16 q1, q1, #2 1528 vrshr.s16 q2, q2, #2 1529 vrshr.s16 q3, q3, #2 1530 vrshr.s16 q4, q4, #2 1531 subs \mx, \mx, #16 1532.ifc \type, put 1533 vqrshrun.s16 d2, q1, #4 1534 vqrshrun.s16 d3, q2, #4 1535 vqrshrun.s16 d4, q3, #4 1536 vqrshrun.s16 d5, q4, #4 1537 vst1.8 {q1}, [\dst, :128]! 1538 vst1.8 {q2}, [\ds2, :128]! 1539.else 1540 vst1.16 {q1, q2}, [\dst, :128]! 1541 vst1.16 {q3, q4}, [\ds2, :128]! 1542.endif 1543 ble 9f 1544 1545 vmov q8, q10 1546 vmov q12, q14 1547 vld1.8 {d18, d19}, [\src]! 1548 vld1.8 {d26, d27}, [\sr2]! 1549 vmovl.u8 q10, d19 1550 vmovl.u8 q9, d18 1551 vmovl.u8 q14, d27 1552 vmovl.u8 q13, d26 1553 b 16b 1554 15559: 1556 add \dst, \dst, \d_strd 1557 add \ds2, \ds2, \d_strd 1558 add \src, \src, \s_strd 1559 add \sr2, \sr2, \s_strd 1560 1561 subs \h, \h, #2 1562 bgt 161b 1563 vpop {q4-q6} 1564 pop {r4-r11,pc} 1565 1566L(\type\()_8tap_v): 1567 cmp \h, #4 1568 ubfx r9, \my, #7, #7 1569 and \my, \my, #0x7f 1570 it gt 1571 movgt \my, r9 1572 add \my, r10, \my, lsl #3 1573 1574 adr r9, L(\type\()_8tap_v_tbl) 1575 ldr r8, [r9, r8, lsl #2] 1576 add r9, r9, r8 1577 bx r9 1578 1579 .align 2 1580L(\type\()_8tap_v_tbl): 1581 .word 1280f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1582 .word 640f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1583 .word 320f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1584 .word 160f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1585 .word 80f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1586 .word 40f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1587 .word 20f - L(\type\()_8tap_v_tbl) + CONFIG_THUMB 1588 158920: // 2xN v 1590.ifc \type, put 1591 bgt 28f 1592 1593 cmp \h, #2 1594 add \my, \my, #2 1595 vld1.32 {d0[]}, [\my] 1596 sub \src, \src, \s_strd 1597 add \ds2, \dst, \d_strd 1598 add \sr2, \src, \s_strd 1599 lsl \s_strd, \s_strd, #1 1600 lsl \d_strd, \d_strd, #1 1601 vmovl.s8 q0, d0 1602 1603 // 2x2 v 1604 load_16 \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1605 interleave_1_16 d1, d2, d3, d4, d5 1606 bgt 24f 1607 vmovl_u8 q8, d1, q9, d2, q10, d3, q11, d4 1608 mul_mla_4 d6, d16, d18, d20, d22 1609 vqrshrun_s16 6, q3, d6 1610 st_16 \d_strd, d6, 2 1611 pop {r4-r11,pc} 1612 161324: // 2x4 v 1614 load_16 \sr2, \src, \s_strd, d6, d7 1615 interleave_1_16 d5, d6, d7 1616 vmovl_u8 q8, d1, q9, d2, q10, d3, q11, d4, q12, d5, q13, d6 1617 vmov d17, d20 1618 vmov d19, d22 1619 vmov d21, d24 1620 vmov d23, d26 1621 mul_mla_4 q3, q8, q9, q10, q11 1622 vqrshrun_s16 6, q3, d6 1623 st_16 \d_strd, d6, 4 1624 pop {r4-r11,pc} 1625 162628: // 2x8, 2x16 v 1627 vpush {q4-q7} 1628 vld1.8 {d0}, [\my, :64] 1629 sub \sr2, \src, \s_strd, lsl #1 1630 add \ds2, \dst, \d_strd 1631 sub \src, \sr2, \s_strd 1632 lsl \d_strd, \d_strd, #1 1633 lsl \s_strd, \s_strd, #1 1634 vmovl.s8 q0, d0 1635 1636 load_16 \src, \sr2, \s_strd, d2, d4, d6, d8, d10, d12, d14 1637 interleave_1_16 d2, d4, d6, d8, d10 1638 interleave_1_16 d10, d12, d14 1639 vmovl_u8 q1, d2, q2, d4, q3, d6, q4, d8, q5, d10, q6, d12 1640 vmov d3, d6 1641 vmov d5, d8 1642 vmov d7, d10 1643 vmov d9, d12 1644216: 1645 subs \h, \h, #8 1646 load_16 \sr2, \src, \s_strd, d16, d18, d20, d22 1647 load_16 \sr2, \src, \s_strd, d24, d26, d28, d30 1648 interleave_1_16 d14, d16, d18, d20, d22 1649 interleave_1_16 d22, d24, d26, d28, d30 1650 vmovl_u8 q7, d14, q8, d16, q9, d18, q10, d20 1651 vmovl_u8 q11, d22, q12, d24, q13, d26, q14, d28 1652 vmov d11, d14 1653 vmov d13, d16 1654 vmov d15, d18 1655 vmov d17, d20 1656 vmov d19, d22 1657 vmov d21, d24 1658 vmov d23, d26 1659 vmov d25, d28 1660 mul_mla_8_4 q1, q2, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12 1661 vqrshrun_s16 6, q1, d2, q2, d4 1662 st_16 \d_strd, d2, 4 1663 st_16 \d_strd, d4, 4 1664 ble 0f 1665 vmov q1, q9 1666 vmov q2, q10 1667 vmov q3, q11 1668 vmov q4, q12 1669 vmov q5, q13 1670 vmov q6, q14 1671 vmov d14, d30 1672 b 216b 16730: 1674 vpop {q4-q7} 1675 pop {r4-r11,pc} 1676.endif 1677 167840: 1679 bgt 480f 1680 1681 // 4x2, 4x4 v 1682 cmp \h, #2 1683 add \my, \my, #2 1684 vld1.32 {d0[]}, [\my] 1685 sub \src, \src, \s_strd 1686 add \ds2, \dst, \d_strd 1687 add \sr2, \src, \s_strd 1688 lsl \s_strd, \s_strd, #1 1689 lsl \d_strd, \d_strd, #1 1690 vmovl.s8 q0, d0 1691 1692 load_32 \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1693 interleave_1_32 d1, d2, d3, d4, d5 1694 vmovl_u8 q8, d1, q9, d2, q10, d3, q11, d4 1695 mul_mla_4 q3, q8, q9, q10, q11 1696 shift_store_4 \type, \d_strd, q3, d6, d7 1697 ble 0f 1698 load_32 \sr2, \src, \s_strd, d6, d7 1699 interleave_1_32 d5, d6, d7 1700 vmovl_u8 q12, d5, q13, d6 1701 mul_mla_4 q3, q10, q11, q12, q13 1702 shift_store_4 \type, \d_strd, q3, d6, d7 17030: 1704 pop {r4-r11,pc} 1705 1706480: // 4x8, 4x16 v 1707 vpush {q4} 1708 vld1.8 {d0}, [\my, :64] 1709 sub \sr2, \src, \s_strd, lsl #1 1710 add \ds2, \dst, \d_strd 1711 sub \src, \sr2, \s_strd 1712 lsl \s_strd, \s_strd, #1 1713 lsl \d_strd, \d_strd, #1 1714 vmovl.s8 q0, d0 1715 1716 load_32 \src, \sr2, \s_strd, d2, d4, d6, d8, d16, d18, d20 1717 interleave_1_32 d2, d4, d6 1718 interleave_1_32 d6, d8, d16, d18, d20 1719 vmovl_u8 q1, d2, q2, d4, q3, d6, q4, d8, q8, d16, q9, d18 1720 172148: 1722 subs \h, \h, #4 1723 load_32 \sr2, \src, \s_strd, d22, d24, d26, d28 1724 interleave_1_32 d20, d22, d24, d26, d28 1725 vmovl_u8 q10, d20, q11, d22, q12, d24, q13, d26 1726 mul_mla_8_2 q1, q2, q1, q2, q3, q4, q8, q9, q10, q11, q12, q13 1727 shift_store_4 \type, \d_strd, q1, d2, d3, q2, d4, d5 1728 ble 0f 1729 subs \h, \h, #4 1730 load_32 \sr2, \src, \s_strd, d30, d2, d4, d6 1731 interleave_1_32 d28, d30, d2, d4, d6 1732 vmovl_u8 q14, d28, q15, d30, q1, d2, q2, d4 1733 mul_mla_8_2 q8, q9, q8, q9, q10, q11, q12, q13, q14, q15, q1, q2 1734 shift_store_4 \type, \d_strd, q8, d16, d17, q9, d18, d19 1735 ble 0f 1736 subs \h, \h, #4 1737 load_32 \sr2, \src, \s_strd, d8, d16, d18, d20 1738 interleave_1_32 d6, d8, d16, d18, d20 1739 vmovl_u8 q3, d6, q4, d8, q8, d16, q9, d18 1740 mul_mla_8_2 q12, q13, q12, q13, q14, q15, q1, q2, q3, q4, q8, q9 1741 shift_store_4 \type, \d_strd, q12, d24, d25, q13, d26, d27 1742 bgt 48b 17430: 1744 vpop {q4} 1745 pop {r4-r11,pc} 1746 174780: 1748 bgt 880f 1749 1750 // 8x2, 8x4 v 1751 cmp \h, #2 1752 add \my, \my, #2 1753 vld1.32 {d0[]}, [\my] 1754 sub \src, \src, \s_strd 1755 add \ds2, \dst, \d_strd 1756 add \sr2, \src, \s_strd 1757 lsl \s_strd, \s_strd, #1 1758 lsl \d_strd, \d_strd, #1 1759 vmovl.s8 q0, d0 1760 1761 load_reg \src, \sr2, \s_strd, d1, d2, d3, d4, d5 1762 vmovl_u8 q8, d1, q9, d2, q10, d3, q11, d4, q12, d5 1763 mul_mla_4 q1, q8, q9, q10, q11 1764 mul_mla_4 q2, q9, q10, q11, q12 1765 shift_store_8 \type, \d_strd, q1, d2, q2, d4 1766 ble 0f 1767 load_reg \sr2, \src, \s_strd, d6, d7 1768 vmovl_u8 q13, d6, q14, d7 1769 mul_mla_4 q1, q10, q11, q12, q13 1770 mul_mla_4 q2, q11, q12, q13, q14 1771 shift_store_8 \type, \d_strd, q1, d2, q2, d4 17720: 1773 pop {r4-r11,pc} 1774 1775880: // 8x6, 8x8, 8x16, 8x32 v 17761680: // 16x8, 16x16, ... 1777320: // 32x8, 32x16, ... 1778640: 17791280: 1780 vpush {q4} 1781 vld1.8 {d0}, [\my, :64] 1782 sub \src, \src, \s_strd 1783 sub \src, \src, \s_strd, lsl #1 1784 vmovl.s8 q0, d0 1785 mov \my, \h 1786168: 1787 add \ds2, \dst, \d_strd 1788 add \sr2, \src, \s_strd 1789 lsl \s_strd, \s_strd, #1 1790 lsl \d_strd, \d_strd, #1 1791 1792 load_reg \src, \sr2, \s_strd, d2, d4, d6, d8, d16, d18, d20 1793 vmovl_u8 q1, d2, q2, d4, q3, d6, q4, d8, q8, d16, q9, d18, q10, d20 1794 179588: 1796 subs \h, \h, #2 1797 load_reg \sr2, \src, \s_strd, d22, d24 1798 vmovl_u8 q11, d22, q12, d24 1799 mul_mla_8_1 q1, q2, q1, q2, q3, q4, q8, q9, q10, q11, q12 1800 shift_store_8 \type, \d_strd, q1, d2, q2, d4 1801 ble 9f 1802 subs \h, \h, #2 1803 load_reg \sr2, \src, \s_strd, d26, d28 1804 vmovl_u8 q13, d26, q14, d28 1805 mul_mla_8_1 q3, q4, q3, q4, q8, q9, q10, q11, q12, q13, q14 1806 shift_store_8 \type, \d_strd, q3, d6, q4, d8 1807 ble 9f 1808 subs \h, \h, #2 1809 load_reg \sr2, \src, \s_strd, d30, d2 1810 vmovl_u8 q15, d30, q1, d2 1811 mul_mla_8_1 q8, q9, q8, q9, q10, q11, q12, q13, q14, q15, q1 1812 shift_store_8 \type, \d_strd, q8, d16, q9, d18 1813 ble 9f 1814 subs \h, \h, #2 1815 load_reg \sr2, \src, \s_strd, d4, d6 1816 vmovl_u8 q2, d4, q3, d6 1817 mul_mla_8_1 q10, q11, q10, q11, q12, q13, q14, q15, q1, q2, q3 1818 shift_store_8 \type, \d_strd, q10, d20, q11, d22 1819 ble 9f 1820 subs \h, \h, #4 1821 load_reg \sr2, \src, \s_strd, d8, d16, d18, d20 1822 vmovl_u8 q4, d8, q8, d16, q9, d18, q10, d20 1823 mul_mla_8_1 q12, q13, q12, q13, q14, q15, q1, q2, q3, q4, q8 1824 mul_mla_8_1 q14, q15, q14, q15, q1, q2, q3, q4, q8, q9, q10 1825 shift_store_8 \type, \d_strd, q12, d24, q13, d26, q14, d28, q15, d30 1826 bgt 88b 18279: 1828 subs \w, \w, #8 1829 ble 0f 1830 asr \s_strd, \s_strd, #1 1831 asr \d_strd, \d_strd, #1 1832 mls \src, \s_strd, \my, \src 1833 mls \dst, \d_strd, \my, \dst 1834 sub \src, \src, \s_strd, lsl #3 1835 mov \h, \my 1836 add \src, \src, #8 1837.ifc \type, put 1838 add \dst, \dst, #8 1839.else 1840 add \dst, \dst, #16 1841.endif 1842 b 168b 18430: 1844 vpop {q4} 1845 pop {r4-r11,pc} 1846 1847160: 1848 bgt 1680b 1849 1850 // 16x2, 16x4 v 1851 add \my, \my, #2 1852 vld1.32 {d0[]}, [\my] 1853 sub \src, \src, \s_strd 1854 add \ds2, \dst, \d_strd 1855 add \sr2, \src, \s_strd 1856 lsl \s_strd, \s_strd, #1 1857 lsl \d_strd, \d_strd, #1 1858 vmovl.s8 q0, d0 1859 1860 cmp \h, #2 1861 load_reg \src, \sr2, \s_strd, q11, q12, q13, q14, q15 1862 vmovl.u8 q1, d22 1863 vmovl.u8 q2, d24 1864 vmovl.u8 q3, d26 1865 vmovl.u8 q8, d28 1866 vmovl.u8 q9, d30 1867 vmovl.u8 q11, d23 1868 vmovl.u8 q12, d25 1869 vmovl.u8 q13, d27 1870 vmovl.u8 q14, d29 1871 vmovl.u8 q15, d31 1872 mul_mla_4 q1, q1, q2, q3, q8 1873 mul_mla_4 q10, q2, q3, q8, q9 1874 mul_mla_4 q2, q11, q12, q13, q14 1875 mul_mla_4 q11, q12, q13, q14, q15 1876 shift_store_16 \type, \d_strd, q1, d2, d3, q2, q10, d20, d21, q11 1877 ble 0f 1878 load_reg \sr2, \src, \s_strd, q10, q11 1879 vmovl.u8 q1, d20 1880 vmovl.u8 q10, d21 1881 vmovl.u8 q12, d22 1882 vmovl.u8 q11, d23 1883 mul_mla_4 q2, q3, q8, q9, q1 1884 mul_mla_4 q3, q13, q14, q15, q10 1885 mul_mla_4 q13, q8, q9, q1, q12 1886 mul_mla_4 q14, q14, q15, q10, q11 1887 shift_store_16 \type, \d_strd, q2, d4, d5, q3, q13, d26, d27, q14 18880: 1889 pop {r4-r11,pc} 1890 1891L(\type\()_8tap_hv): 1892 cmp \h, #4 1893 ubfx r9, \my, #7, #7 1894 and \my, \my, #0x7f 1895 it gt 1896 movgt \my, r9 1897 add \my, r10, \my, lsl #3 1898 1899 adr r9, L(\type\()_8tap_hv_tbl) 1900 ldr r8, [r9, r8, lsl #2] 1901 add r9, r9, r8 1902 bx r9 1903 1904 .align 2 1905L(\type\()_8tap_hv_tbl): 1906 .word 1280f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1907 .word 640f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1908 .word 320f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1909 .word 160f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1910 .word 80f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1911 .word 40f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1912 .word 20f - L(\type\()_8tap_hv_tbl) + CONFIG_THUMB 1913 191420: 1915.ifc \type, put 1916 add \mx, \mx, #2 1917 vld1.32 {d0[]}, [\mx] 1918 bgt 280f 1919 add \my, \my, #2 1920 vld1.32 {d2[]}, [\my] 1921 1922 // 2x2, 2x4 hv 1923 sub \sr2, \src, #1 1924 sub \src, \sr2, \s_strd 1925 add \ds2, \dst, \d_strd 1926 lsl \s_strd, \s_strd, #1 1927 lsl \d_strd, \d_strd, #1 1928 vmovl.s8 q0, d0 1929 vmovl.s8 q1, d2 1930 1931 1932 vld1.8 {d26}, [\src], \s_strd 1933 vmovl.u8 q13, d26 1934 vext.8 q14, q13, q13, #2 1935 vmul.s16 d26, d26, d0 1936 vmul.s16 d28, d28, d0 1937 vpadd.s16 d26, d26, d28 1938 vpadd.s16 d26, d26, d26 1939 vrshr.s16 d16, d26, #2 1940 bl L(\type\()_8tap_filter_2) 1941 1942 vext.8 d16, d16, d16, #4 1943 vmov d17, d26 1944 vext.8 d16, d16, d26, #4 1945 19462: 1947 bl L(\type\()_8tap_filter_2) 1948 1949 vext.8 d18, d17, d26, #4 1950 vmull.s16 q2, d16, d2[0] 1951 vmlal.s16 q2, d17, d2[1] 1952 vmlal.s16 q2, d18, d2[2] 1953 vmlal.s16 q2, d26, d2[3] 1954 1955 vqrshrn.s32 d4, q2, #\shift_hv 1956 vqmovun.s16 d4, q2 1957 subs \h, \h, #2 1958 vst1.16 {d4[0]}, [\dst, :16], \d_strd 1959 vst1.16 {d4[1]}, [\ds2, :16], \d_strd 1960 ble 0f 1961 vmov d16, d18 1962 vmov d17, d26 1963 b 2b 1964 1965280: // 2x8, 2x16, 2x32 hv 1966 vld1.8 {d2}, [\my, :64] 1967 sub \src, \src, #1 1968 sub \sr2, \src, \s_strd, lsl #1 1969 sub \src, \sr2, \s_strd 1970 add \ds2, \dst, \d_strd 1971 lsl \s_strd, \s_strd, #1 1972 lsl \d_strd, \d_strd, #1 1973 vmovl.s8 q0, d0 1974 vmovl.s8 q1, d2 1975 1976 vld1.8 {d26}, [\src], \s_strd 1977 vmovl.u8 q13, d26 1978 vext.8 q14, q13, q13, #2 1979 vmul.s16 d26, d26, d0 1980 vmul.s16 d28, d28, d0 1981 vpadd.s16 d26, d26, d28 1982 vpadd.s16 d26, d26, d26 1983 vrshr.s16 d16, d26, #2 1984 1985 bl L(\type\()_8tap_filter_2) 1986 vext.8 d16, d16, d16, #4 1987 vmov d17, d26 1988 vext.8 d16, d16, d26, #4 1989 bl L(\type\()_8tap_filter_2) 1990 vext.8 d18, d17, d26, #4 1991 vmov d19, d26 1992 bl L(\type\()_8tap_filter_2) 1993 vext.8 d20, d19, d26, #4 1994 vmov d21, d26 1995 199628: 1997 bl L(\type\()_8tap_filter_2) 1998 vext.8 d22, d21, d26, #4 1999 vmull.s16 q2, d16, d2[0] 2000 vmlal.s16 q2, d17, d2[1] 2001 vmlal.s16 q2, d18, d2[2] 2002 vmlal.s16 q2, d19, d2[3] 2003 vmlal.s16 q2, d20, d3[0] 2004 vmlal.s16 q2, d21, d3[1] 2005 vmlal.s16 q2, d22, d3[2] 2006 vmlal.s16 q2, d26, d3[3] 2007 2008 vqrshrn.s32 d4, q2, #\shift_hv 2009 vqmovun.s16 d4, q2 2010 subs \h, \h, #2 2011 vst1.16 {d4[0]}, [\dst, :16], \d_strd 2012 vst1.16 {d4[1]}, [\ds2, :16], \d_strd 2013 ble 0f 2014 vmov d16, d18 2015 vmov d17, d19 2016 vmov d18, d20 2017 vmov d19, d21 2018 vmov d20, d22 2019 vmov d21, d26 2020 b 28b 2021 20220: 2023 pop {r4-r11,pc} 2024 2025L(\type\()_8tap_filter_2): 2026 vld1.8 {d28}, [\sr2], \s_strd 2027 vld1.8 {d30}, [\src], \s_strd 2028 vext.8 d29, d28, d28, #1 2029 vext.8 d31, d30, d30, #1 2030 vmovl.u8 q13, d28 2031 vmovl.u8 q14, d29 2032 vmov d27, d28 2033 vmovl.u8 q14, d30 2034 vmovl.u8 q15, d31 2035 vtrn.32 d26, d28 2036 vtrn.32 d27, d30 2037 vmul.s16 d26, d26, d0[0] 2038 vmla.s16 d26, d27, d0[1] 2039 vmla.s16 d26, d28, d0[2] 2040 vmla.s16 d26, d30, d0[3] 2041 vrshr.s16 d26, d26, #2 2042 vext.8 d27, d26, d26, #4 2043 bx lr 2044.endif 2045 204640: 2047 add \mx, \mx, #2 2048 vld1.32 {d0[]}, [\mx] 2049 bgt 480f 2050 add \my, \my, #2 2051 vld1.32 {d2[]}, [\my] 2052 sub \sr2, \src, #1 2053 sub \src, \sr2, \s_strd 2054 add \ds2, \dst, \d_strd 2055 lsl \s_strd, \s_strd, #1 2056 lsl \d_strd, \d_strd, #1 2057 vmovl.s8 q0, d0 2058 vmovl.s8 q1, d2 2059 2060 // 4x2, 4x4 hv 2061 vld1.8 {d30}, [\src], \s_strd 2062 vmovl.u8 q14, d30 2063 vext.8 d27, d28, d29, #2 2064 vext.8 d30, d28, d29, #4 2065 vext.8 d31, d28, d29, #6 2066 vmul.s16 d26, d28, d0[0] 2067 vmla.s16 d26, d27, d0[1] 2068 vmla.s16 d26, d30, d0[2] 2069 vmla.s16 d26, d31, d0[3] 2070 vrshr.s16 d16, d26, #2 2071 2072 bl L(\type\()_8tap_filter_4) 2073 vmov d17, d26 2074 vmov d18, d27 2075 20764: 2077 bl L(\type\()_8tap_filter_4) 2078 vmull.s16 q2, d16, d2[0] 2079 vmlal.s16 q2, d17, d2[1] 2080 vmlal.s16 q2, d18, d2[2] 2081 vmlal.s16 q2, d26, d2[3] 2082 vmull.s16 q3, d17, d2[0] 2083 vmlal.s16 q3, d18, d2[1] 2084 vmlal.s16 q3, d26, d2[2] 2085 vmlal.s16 q3, d27, d2[3] 2086 vqrshrn.s32 d4, q2, #\shift_hv 2087 vqrshrn.s32 d6, q3, #\shift_hv 2088 subs \h, \h, #2 2089.ifc \type, put 2090 vqmovun.s16 d4, q2 2091 vqmovun.s16 d6, q3 2092 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2093 vst1.32 {d6[0]}, [\ds2, :32], \d_strd 2094.else 2095 vst1.16 {d4}, [\dst, :64], \d_strd 2096 vst1.16 {d6}, [\ds2, :64], \d_strd 2097.endif 2098 ble 0f 2099 vmov d16, d18 2100 vmov d17, d26 2101 vmov d18, d27 2102 b 4b 2103 2104480: // 4x8, 4x16, 4x32 hv 2105 vld1.8 {d2}, [\my, :64] 2106 sub \src, \src, #1 2107 sub \sr2, \src, \s_strd, lsl #1 2108 sub \src, \sr2, \s_strd 2109 add \ds2, \dst, \d_strd 2110 lsl \s_strd, \s_strd, #1 2111 lsl \d_strd, \d_strd, #1 2112 vmovl.s8 q0, d0 2113 vmovl.s8 q1, d2 2114 2115 vld1.8 {d30}, [\src], \s_strd 2116 vmovl.u8 q14, d30 2117 vext.8 d27, d28, d29, #2 2118 vext.8 d30, d28, d29, #4 2119 vext.8 d31, d28, d29, #6 2120 vmul.s16 d26, d28, d0[0] 2121 vmla.s16 d26, d27, d0[1] 2122 vmla.s16 d26, d30, d0[2] 2123 vmla.s16 d26, d31, d0[3] 2124 vrshr.s16 d16, d26, #2 2125 2126 bl L(\type\()_8tap_filter_4) 2127 vmov d17, d26 2128 vmov d18, d27 2129 bl L(\type\()_8tap_filter_4) 2130 vmov d19, d26 2131 vmov d20, d27 2132 bl L(\type\()_8tap_filter_4) 2133 vmov d21, d26 2134 vmov d22, d27 2135 213648: 2137 bl L(\type\()_8tap_filter_4) 2138 vmull.s16 q2, d16, d2[0] 2139 vmlal.s16 q2, d17, d2[1] 2140 vmlal.s16 q2, d18, d2[2] 2141 vmlal.s16 q2, d19, d2[3] 2142 vmlal.s16 q2, d20, d3[0] 2143 vmlal.s16 q2, d21, d3[1] 2144 vmlal.s16 q2, d22, d3[2] 2145 vmlal.s16 q2, d26, d3[3] 2146 vmull.s16 q3, d17, d2[0] 2147 vmlal.s16 q3, d18, d2[1] 2148 vmlal.s16 q3, d19, d2[2] 2149 vmlal.s16 q3, d20, d2[3] 2150 vmlal.s16 q3, d21, d3[0] 2151 vmlal.s16 q3, d22, d3[1] 2152 vmlal.s16 q3, d26, d3[2] 2153 vmlal.s16 q3, d27, d3[3] 2154 vqrshrn.s32 d4, q2, #\shift_hv 2155 vqrshrn.s32 d6, q3, #\shift_hv 2156 subs \h, \h, #2 2157.ifc \type, put 2158 vqmovun.s16 d4, q2 2159 vqmovun.s16 d6, q3 2160 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2161 vst1.32 {d6[0]}, [\ds2, :32], \d_strd 2162.else 2163 vst1.16 {d4}, [\dst, :64], \d_strd 2164 vst1.16 {d6}, [\ds2, :64], \d_strd 2165.endif 2166 ble 0f 2167 vmov d16, d18 2168 vmov d17, d19 2169 vmov d18, d20 2170 vmov d19, d21 2171 vmov d20, d22 2172 vmov d21, d26 2173 vmov d22, d27 2174 b 48b 21750: 2176 pop {r4-r11,pc} 2177 2178L(\type\()_8tap_filter_4): 2179 vld1.8 {d30}, [\sr2], \s_strd 2180 vld1.8 {d31}, [\src], \s_strd 2181 vmovl.u8 q14, d30 2182 vext.8 d27, d28, d29, #2 2183 vext.8 d30, d28, d29, #4 2184 vext.8 d1, d28, d29, #6 2185 vmul.s16 d26, d28, d0[0] 2186 vmla.s16 d26, d27, d0[1] 2187 vmla.s16 d26, d30, d0[2] 2188 vmla.s16 d26, d1, d0[3] 2189 2190 vmovl.u8 q14, d31 2191 vext.8 d30, d28, d29, #2 2192 vext.8 d31, d28, d29, #4 2193 vext.8 d1, d28, d29, #6 2194 vmul.s16 d27, d28, d0[0] 2195 vmla.s16 d27, d30, d0[1] 2196 vmla.s16 d27, d31, d0[2] 2197 vmla.s16 d27, d1, d0[3] 2198 vrshr.s16 d26, d26, #2 2199 vrshr.s16 d27, d27, #2 2200 bx lr 2201 220280: 2203160: 2204320: 2205 bgt 880f 2206 vpush {q4-q7} 2207 add \my, \my, #2 2208 vld1.8 {d0}, [\mx, :64] 2209 vld1.32 {d2[]}, [\my] 2210 sub \src, \src, #3 2211 sub \src, \src, \s_strd 2212 vmovl.s8 q0, d0 2213 vmovl.s8 q1, d2 2214 mov \my, \h 2215 2216164: // 8x2, 8x4, 16x2, 16x4, 32x2, 32x4 hv 2217 add \ds2, \dst, \d_strd 2218 add \sr2, \src, \s_strd 2219 lsl \d_strd, \d_strd, #1 2220 lsl \s_strd, \s_strd, #1 2221 2222 vld1.8 {q14}, [\src], \s_strd 2223 vmovl.u8 q12, d28 2224 vmovl.u8 q13, d29 2225 vmul.s16 q10, q12, d0[0] 2226.irpc i, 123 2227 vext.8 q14, q12, q13, #(2*\i) 2228 vmla.s16 q10, q14, d0[\i] 2229.endr 2230.irpc i, 4567 2231 vext.8 q14, q12, q13, #(2*\i) 2232 vmla.s16 q10, q14, d1[\i-4] 2233.endr 2234 vrshr.s16 q3, q10, #2 2235 2236 bl L(\type\()_8tap_filter_8) 2237 vmov q4, q10 2238 vmov q5, q11 2239 22408: 2241 bl L(\type\()_8tap_filter_8) 2242 vmull.s16 q12, d6, d2[0] 2243 vmull.s16 q13, d7, d2[0] 2244 vmull.s16 q14, d8, d2[0] 2245 vmull.s16 q15, d9, d2[0] 2246 vmlal.s16 q12, d8, d2[1] 2247 vmlal.s16 q13, d9, d2[1] 2248 vmlal.s16 q14, d10, d2[1] 2249 vmlal.s16 q15, d11, d2[1] 2250 vmlal.s16 q12, d10, d2[2] 2251 vmlal.s16 q13, d11, d2[2] 2252 vmlal.s16 q14, d20, d2[2] 2253 vmlal.s16 q15, d21, d2[2] 2254 vmlal.s16 q12, d20, d2[3] 2255 vmlal.s16 q13, d21, d2[3] 2256 vmlal.s16 q14, d22, d2[3] 2257 vmlal.s16 q15, d23, d2[3] 2258 vqrshrn.s32 d24, q12, #\shift_hv 2259 vqrshrn.s32 d25, q13, #\shift_hv 2260 vqrshrn.s32 d28, q14, #\shift_hv 2261 vqrshrn.s32 d29, q15, #\shift_hv 2262 subs \h, \h, #2 2263.ifc \type, put 2264 vqmovun.s16 d24, q12 2265 vqmovun.s16 d28, q14 2266 vst1.8 {d24}, [\dst, :64], \d_strd 2267 vst1.8 {d28}, [\ds2, :64], \d_strd 2268.else 2269 vst1.16 {q12}, [\dst, :128], \d_strd 2270 vst1.16 {q14}, [\ds2, :128], \d_strd 2271.endif 2272 ble 9f 2273 vmov q3, q5 2274 vmov q4, q10 2275 vmov q5, q11 2276 b 8b 22779: 2278 subs \w, \w, #8 2279 ble 0f 2280 asr \s_strd, \s_strd, #1 2281 asr \d_strd, \d_strd, #1 2282 mls \src, \s_strd, \my, \src 2283 mls \dst, \d_strd, \my, \dst 2284 sub \src, \src, \s_strd, lsl #2 2285 mov \h, \my 2286 add \src, \src, #8 2287.ifc \type, put 2288 add \dst, \dst, #8 2289.else 2290 add \dst, \dst, #16 2291.endif 2292 b 164b 2293 2294880: // 8x8, 8x16, ..., 16x8, ..., 32x8, ... hv 2295640: 22961280: 2297 vpush {q4-q7} 2298 vld1.8 {d0}, [\mx, :64] 2299 vld1.8 {d2}, [\my, :64] 2300 sub \src, \src, #3 2301 sub \src, \src, \s_strd 2302 sub \src, \src, \s_strd, lsl #1 2303 vmovl.s8 q0, d0 2304 vmovl.s8 q1, d2 2305 mov \my, \h 2306 2307168: 2308 add \ds2, \dst, \d_strd 2309 add \sr2, \src, \s_strd 2310 lsl \d_strd, \d_strd, #1 2311 lsl \s_strd, \s_strd, #1 2312 2313 vld1.8 {q14}, [\src], \s_strd 2314 vmovl.u8 q12, d28 2315 vmovl.u8 q13, d29 2316 vmul.s16 q10, q12, d0[0] 2317.irpc i, 123 2318 vext.8 q14, q12, q13, #(2*\i) 2319 vmla.s16 q10, q14, d0[\i] 2320.endr 2321.irpc i, 4567 2322 vext.8 q14, q12, q13, #(2*\i) 2323 vmla.s16 q10, q14, d1[\i-4] 2324.endr 2325 vrshr.s16 q3, q10, #2 2326 2327 bl L(\type\()_8tap_filter_8) 2328 vmov q4, q10 2329 vmov q5, q11 2330 bl L(\type\()_8tap_filter_8) 2331 vmov q6, q10 2332 vmov q7, q11 2333 bl L(\type\()_8tap_filter_8) 2334 vmov q8, q10 2335 vmov q9, q11 2336 233788: 2338 bl L(\type\()_8tap_filter_8) 2339 vmull.s16 q12, d6, d2[0] 2340 vmull.s16 q13, d7, d2[0] 2341 vmull.s16 q14, d8, d2[0] 2342 vmull.s16 q15, d9, d2[0] 2343 vmlal.s16 q12, d8, d2[1] 2344 vmlal.s16 q13, d9, d2[1] 2345 vmlal.s16 q14, d10, d2[1] 2346 vmlal.s16 q15, d11, d2[1] 2347 vmlal.s16 q12, d10, d2[2] 2348 vmlal.s16 q13, d11, d2[2] 2349 vmlal.s16 q14, d12, d2[2] 2350 vmlal.s16 q15, d13, d2[2] 2351 vmlal.s16 q12, d12, d2[3] 2352 vmlal.s16 q13, d13, d2[3] 2353 vmlal.s16 q14, d14, d2[3] 2354 vmlal.s16 q15, d15, d2[3] 2355 vmlal.s16 q12, d14, d3[0] 2356 vmlal.s16 q13, d15, d3[0] 2357 vmlal.s16 q14, d16, d3[0] 2358 vmlal.s16 q15, d17, d3[0] 2359 vmlal.s16 q12, d16, d3[1] 2360 vmlal.s16 q13, d17, d3[1] 2361 vmlal.s16 q14, d18, d3[1] 2362 vmlal.s16 q15, d19, d3[1] 2363 vmlal.s16 q12, d18, d3[2] 2364 vmlal.s16 q13, d19, d3[2] 2365 vmlal.s16 q14, d20, d3[2] 2366 vmlal.s16 q15, d21, d3[2] 2367 vmlal.s16 q12, d20, d3[3] 2368 vmlal.s16 q13, d21, d3[3] 2369 vmlal.s16 q14, d22, d3[3] 2370 vmlal.s16 q15, d23, d3[3] 2371 vqrshrn.s32 d24, q12, #\shift_hv 2372 vqrshrn.s32 d25, q13, #\shift_hv 2373 vqrshrn.s32 d28, q14, #\shift_hv 2374 vqrshrn.s32 d29, q15, #\shift_hv 2375 subs \h, \h, #2 2376.ifc \type, put 2377 vqmovun.s16 d24, q12 2378 vqmovun.s16 d28, q14 2379 vst1.8 {d24}, [\dst, :64], \d_strd 2380 vst1.8 {d28}, [\ds2, :64], \d_strd 2381.else 2382 vst1.16 {q12}, [\dst, :128], \d_strd 2383 vst1.16 {q14}, [\ds2, :128], \d_strd 2384.endif 2385 ble 9f 2386 vmov q3, q5 2387 vmov q4, q6 2388 vmov q5, q7 2389 vmov q6, q8 2390 vmov q7, q9 2391 vmov q8, q10 2392 vmov q9, q11 2393 b 88b 23949: 2395 subs \w, \w, #8 2396 ble 0f 2397 asr \s_strd, \s_strd, #1 2398 asr \d_strd, \d_strd, #1 2399 mls \src, \s_strd, \my, \src 2400 mls \dst, \d_strd, \my, \dst 2401 sub \src, \src, \s_strd, lsl #3 2402 mov \h, \my 2403 add \src, \src, #8 2404.ifc \type, put 2405 add \dst, \dst, #8 2406.else 2407 add \dst, \dst, #16 2408.endif 2409 b 168b 24100: 2411 vpop {q4-q7} 2412 pop {r4-r11,pc} 2413 2414L(\type\()_8tap_filter_8): 2415 vld1.8 {q14}, [\sr2], \s_strd 2416 vld1.8 {q15}, [\src], \s_strd 2417 vmovl.u8 q12, d28 2418 vmovl.u8 q13, d29 2419 vmul.s16 q10, q12, d0[0] 2420.irpc i, 123 2421 vext.8 q14, q12, q13, #(2*\i) 2422 vmla.s16 q10, q14, d0[\i] 2423.endr 2424.irpc i, 4567 2425 vext.8 q14, q12, q13, #(2*\i) 2426 vmla.s16 q10, q14, d1[\i-4] 2427.endr 2428 vmovl.u8 q12, d30 2429 vmovl.u8 q13, d31 2430 vmul.s16 q11, q12, d0[0] 2431.irpc i, 123 2432 vext.8 q14, q12, q13, #(2*\i) 2433 vmla.s16 q11, q14, d0[\i] 2434.endr 2435.irpc i, 4567 2436 vext.8 q14, q12, q13, #(2*\i) 2437 vmla.s16 q11, q14, d1[\i-4] 2438.endr 2439 vrshr.s16 q10, q10, #2 2440 vrshr.s16 q11, q11, #2 2441 bx lr 2442endfunc 2443 2444 2445function \type\()_bilin_8bpc_neon, export=1 2446 push {r4-r11,lr} 2447 ldrd r4, r5, [sp, #36] 2448 ldrd r6, r7, [sp, #44] 2449 vdup.8 d1, \mx 2450 vdup.8 d3, \my 2451 rsb r8, \mx, #16 2452 rsb r9, \my, #16 2453 vdup.8 d0, r8 2454 vdup.8 d2, r9 2455.ifc \type, prep 2456 lsl \d_strd, \w, #1 2457.endif 2458 clz r8, \w 2459 cmp \mx, #0 2460 sub r8, r8, #24 2461 bne L(\type\()_bilin_h) 2462 cmp \my, #0 2463 bne L(\type\()_bilin_v) 2464 b \type\()_neon 2465 2466L(\type\()_bilin_h): 2467 cmp \my, #0 2468 bne L(\type\()_bilin_hv) 2469 2470 adr r9, L(\type\()_bilin_h_tbl) 2471 ldr r8, [r9, r8, lsl #2] 2472 add r9, r9, r8 2473 bx r9 2474 2475 .align 2 2476L(\type\()_bilin_h_tbl): 2477 .word 1280f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2478 .word 640f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2479 .word 320f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2480 .word 160f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2481 .word 80f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2482 .word 40f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2483 .word 20f - L(\type\()_bilin_h_tbl) + CONFIG_THUMB 2484 248520: // 2xN h 2486.ifc \type, put 2487 add \ds2, \dst, \d_strd 2488 add \sr2, \src, \s_strd 2489 lsl \d_strd, \d_strd, #1 2490 lsl \s_strd, \s_strd, #1 24912: 2492 vld1.32 {d4[]}, [\src], \s_strd 2493 vld1.32 {d6[]}, [\sr2], \s_strd 2494 vext.8 d5, d4, d4, #1 2495 vext.8 d7, d6, d6, #1 2496 vtrn.16 q2, q3 2497 subs \h, \h, #2 2498 vmull.u8 q3, d4, d0 2499 vmlal.u8 q3, d5, d1 2500 vqrshrn.u16 d4, q3, #4 2501 vst1.16 {d4[0]}, [\dst, :16], \d_strd 2502 vst1.16 {d4[1]}, [\ds2, :16], \d_strd 2503 bgt 2b 2504 pop {r4-r11,pc} 2505.endif 2506 250740: // 4xN h 2508 add \ds2, \dst, \d_strd 2509 add \sr2, \src, \s_strd 2510 lsl \d_strd, \d_strd, #1 2511 lsl \s_strd, \s_strd, #1 25124: 2513 vld1.8 {d4}, [\src], \s_strd 2514 vld1.8 {d6}, [\sr2], \s_strd 2515 vext.8 d5, d4, d4, #1 2516 vext.8 d7, d6, d6, #1 2517 vtrn.32 q2, q3 2518 subs \h, \h, #2 2519 vmull.u8 q3, d4, d0 2520 vmlal.u8 q3, d5, d1 2521.ifc \type, put 2522 vqrshrn.u16 d4, q3, #4 2523 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2524 vst1.32 {d4[1]}, [\ds2, :32], \d_strd 2525.else 2526 vst1.16 {d6}, [\dst, :64], \d_strd 2527 vst1.16 {d7}, [\ds2, :64], \d_strd 2528.endif 2529 bgt 4b 2530 pop {r4-r11,pc} 2531 253280: // 8xN h 2533 add \ds2, \dst, \d_strd 2534 add \sr2, \src, \s_strd 2535 lsl \d_strd, \d_strd, #1 2536 lsl \s_strd, \s_strd, #1 25378: 2538 vld1.8 {q8}, [\src], \s_strd 2539 vld1.8 {q10}, [\sr2], \s_strd 2540 vext.8 q9, q8, q8, #1 2541 vext.8 q11, q10, q10, #1 2542 subs \h, \h, #2 2543 vmull.u8 q8, d16, d0 2544 vmull.u8 q10, d20, d0 2545 vmlal.u8 q8, d18, d1 2546 vmlal.u8 q10, d22, d1 2547.ifc \type, put 2548 vqrshrn.u16 d16, q8, #4 2549 vqrshrn.u16 d18, q10, #4 2550 vst1.8 {d16}, [\dst, :64], \d_strd 2551 vst1.8 {d18}, [\ds2, :64], \d_strd 2552.else 2553 vst1.16 {q8}, [\dst, :128], \d_strd 2554 vst1.16 {q10}, [\ds2, :128], \d_strd 2555.endif 2556 bgt 8b 2557 pop {r4-r11,pc} 2558160: 2559320: 2560640: 25611280: // 16xN, 32xN, ... h 2562 add \ds2, \dst, \d_strd 2563 add \sr2, \src, \s_strd 2564 lsl \s_strd, \s_strd, #1 2565 2566 sub \s_strd, \s_strd, \w 2567 sub \s_strd, \s_strd, #8 2568.ifc \type, put 2569 lsl \d_strd, \d_strd, #1 2570 sub \d_strd, \d_strd, \w 2571.endif 2572161: 2573 vld1.8 {d16}, [\src]! 2574 vld1.8 {d22}, [\sr2]! 2575 mov \mx, \w 2576 257716: 2578 vld1.8 {d17,d18}, [\src]! 2579 vld1.8 {d23,d24}, [\sr2]! 2580 vext.8 q10, q8, q9, #1 2581 vext.8 q13, q11, q12, #1 2582 vmull.u8 q2, d16, d0 2583 vmull.u8 q3, d17, d0 2584 vmull.u8 q14, d22, d0 2585 vmull.u8 q15, d23, d0 2586 vmlal.u8 q2, d20, d1 2587 vmlal.u8 q3, d21, d1 2588 vmlal.u8 q14, d26, d1 2589 vmlal.u8 q15, d27, d1 2590 subs \mx, \mx, #16 2591.ifc \type, put 2592 vqrshrn.u16 d4, q2, #4 2593 vqrshrn.u16 d5, q3, #4 2594 vqrshrn.u16 d28, q14, #4 2595 vqrshrn.u16 d29, q15, #4 2596 vst1.8 {q2}, [\dst, :128]! 2597 vst1.8 {q14}, [\ds2, :128]! 2598.else 2599 vst1.16 {q2, q3}, [\dst, :128]! 2600 vst1.16 {q14, q15}, [\ds2, :128]! 2601.endif 2602 ble 9f 2603 2604 vmov d16, d18 2605 vmov d22, d24 2606 b 16b 2607 26089: 2609 add \dst, \dst, \d_strd 2610 add \ds2, \ds2, \d_strd 2611 add \src, \src, \s_strd 2612 add \sr2, \sr2, \s_strd 2613 2614 subs \h, \h, #2 2615 bgt 161b 2616 pop {r4-r11,pc} 2617 2618L(\type\()_bilin_v): 2619 cmp \h, #4 2620 adr r9, L(\type\()_bilin_v_tbl) 2621 ldr r8, [r9, r8, lsl #2] 2622 add r9, r9, r8 2623 bx r9 2624 2625 .align 2 2626L(\type\()_bilin_v_tbl): 2627 .word 1280f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2628 .word 640f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2629 .word 320f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2630 .word 160f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2631 .word 80f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2632 .word 40f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2633 .word 20f - L(\type\()_bilin_v_tbl) + CONFIG_THUMB 2634 263520: // 2xN v 2636.ifc \type, put 2637 cmp \h, #2 2638 add \ds2, \dst, \d_strd 2639 add \sr2, \src, \s_strd 2640 lsl \s_strd, \s_strd, #1 2641 lsl \d_strd, \d_strd, #1 2642 2643 // 2x2 v 2644 vld1.16 {d16[]}, [\src], \s_strd 2645 bgt 24f 2646 vld1.16 {d17[]}, [\sr2], \s_strd 2647 vld1.16 {d18[]}, [\src], \s_strd 2648 vext.8 d16, d16, d17, #6 2649 vext.8 d17, d17, d18, #6 2650 vmull.u8 q2, d16, d2 2651 vmlal.u8 q2, d17, d3 2652 vqrshrn.u16 d4, q2, #4 2653 vst1.16 {d4[0]}, [\dst, :16] 2654 vst1.16 {d4[1]}, [\ds2, :16] 2655 pop {r4-r11,pc} 265624: // 2x4, 2x8, ... v 2657 vld1.16 {d17[]}, [\sr2], \s_strd 2658 vld1.16 {d18[]}, [\src], \s_strd 2659 vld1.16 {d19[]}, [\sr2], \s_strd 2660 vld1.16 {d20[]}, [\src], \s_strd 2661 vext.8 d16, d16, d17, #6 2662 vext.8 d17, d17, d18, #6 2663 vext.8 d18, d18, d19, #6 2664 vext.8 d19, d19, d20, #6 2665 vtrn.32 d16, d18 2666 vtrn.32 d17, d19 2667 vmull.u8 q2, d16, d2 2668 vmlal.u8 q2, d17, d3 2669 subs \h, \h, #4 2670 vqrshrn.u16 d4, q2, #4 2671 vst1.16 {d4[0]}, [\dst, :16], \d_strd 2672 vst1.16 {d4[1]}, [\ds2, :16], \d_strd 2673 vst1.16 {d4[2]}, [\dst, :16], \d_strd 2674 vst1.16 {d4[3]}, [\ds2, :16], \d_strd 2675 ble 0f 2676 vmov d16, d20 2677 b 24b 26780: 2679 pop {r4-r11,pc} 2680.endif 2681 268240: // 4xN v 2683 add \ds2, \dst, \d_strd 2684 add \sr2, \src, \s_strd 2685 lsl \s_strd, \s_strd, #1 2686 lsl \d_strd, \d_strd, #1 2687 vld1.32 {d16[]}, [\src], \s_strd 26884: 2689 vld1.32 {d17[]}, [\sr2], \s_strd 2690 vld1.32 {d18[]}, [\src], \s_strd 2691 vext.8 d16, d16, d17, #4 2692 vext.8 d17, d17, d18, #4 2693 vmull.u8 q2, d16, d2 2694 vmlal.u8 q2, d17, d3 2695 subs \h, \h, #2 2696.ifc \type, put 2697 vqrshrn.u16 d4, q2, #4 2698 vst1.32 {d4[0]}, [\dst, :32], \d_strd 2699 vst1.32 {d4[1]}, [\ds2, :32], \d_strd 2700.else 2701 vst1.16 {d4}, [\dst, :64], \d_strd 2702 vst1.16 {d5}, [\ds2, :64], \d_strd 2703.endif 2704 ble 0f 2705 vmov d16, d18 2706 b 4b 27070: 2708 pop {r4-r11,pc} 2709 271080: // 8xN v 2711 add \ds2, \dst, \d_strd 2712 add \sr2, \src, \s_strd 2713 lsl \s_strd, \s_strd, #1 2714 lsl \d_strd, \d_strd, #1 2715 vld1.8 {d16}, [\src], \s_strd 27168: 2717 vld1.8 {d17}, [\sr2], \s_strd 2718 vld1.8 {d18}, [\src], \s_strd 2719 vmull.u8 q2, d16, d2 2720 vmull.u8 q3, d17, d2 2721 vmlal.u8 q2, d17, d3 2722 vmlal.u8 q3, d18, d3 2723 subs \h, \h, #2 2724.ifc \type, put 2725 vqrshrn.u16 d4, q2, #4 2726 vqrshrn.u16 d6, q3, #4 2727 vst1.8 {d4}, [\dst, :64], \d_strd 2728 vst1.8 {d6}, [\ds2, :64], \d_strd 2729.else 2730 vst1.16 {q2}, [\dst, :128], \d_strd 2731 vst1.16 {q3}, [\ds2, :128], \d_strd 2732.endif 2733 ble 0f 2734 vmov d16, d18 2735 b 8b 27360: 2737 pop {r4-r11,pc} 2738 2739160: // 16xN, 32xN, ... 2740320: 2741640: 27421280: 2743 mov \my, \h 27441: 2745 add \ds2, \dst, \d_strd 2746 add \sr2, \src, \s_strd 2747 lsl \s_strd, \s_strd, #1 2748 lsl \d_strd, \d_strd, #1 2749 2750 vld1.8 {q8}, [\src], \s_strd 27512: 2752 vld1.8 {q9}, [\sr2], \s_strd 2753 vld1.8 {q10}, [\src], \s_strd 2754 vmull.u8 q12, d16, d2 2755 vmull.u8 q13, d17, d2 2756 vmull.u8 q14, d18, d2 2757 vmull.u8 q15, d19, d2 2758 vmlal.u8 q12, d18, d3 2759 vmlal.u8 q13, d19, d3 2760 vmlal.u8 q14, d20, d3 2761 vmlal.u8 q15, d21, d3 2762 subs \h, \h, #2 2763.ifc \type, put 2764 vqrshrn.u16 d24, q12, #4 2765 vqrshrn.u16 d25, q13, #4 2766 vqrshrn.u16 d28, q14, #4 2767 vqrshrn.u16 d29, q15, #4 2768 vst1.8 {q12}, [\dst, :128], \d_strd 2769 vst1.8 {q14}, [\ds2, :128], \d_strd 2770.else 2771 vst1.16 {q12, q13}, [\dst, :128], \d_strd 2772 vst1.16 {q14, q15}, [\ds2, :128], \d_strd 2773.endif 2774 ble 9f 2775 vmov q8, q10 2776 b 2b 27779: 2778 subs \w, \w, #16 2779 ble 0f 2780 asr \s_strd, \s_strd, #1 2781 asr \d_strd, \d_strd, #1 2782 mls \src, \s_strd, \my, \src 2783 mls \dst, \d_strd, \my, \dst 2784 sub \src, \src, \s_strd, lsl #1 2785 mov \h, \my 2786 add \src, \src, #16 2787.ifc \type, put 2788 add \dst, \dst, #16 2789.else 2790 add \dst, \dst, #32 2791.endif 2792 b 1b 27930: 2794 pop {r4-r11,pc} 2795 2796L(\type\()_bilin_hv): 2797 vmovl.u8 q2, d2 2798 vmovl.u8 q3, d3 2799 adr r9, L(\type\()_bilin_hv_tbl) 2800 ldr r8, [r9, r8, lsl #2] 2801 add r9, r9, r8 2802 bx r9 2803 2804 .align 2 2805L(\type\()_bilin_hv_tbl): 2806 .word 1280f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2807 .word 640f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2808 .word 320f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2809 .word 160f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2810 .word 80f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2811 .word 40f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2812 .word 20f - L(\type\()_bilin_hv_tbl) + CONFIG_THUMB 2813 281420: // 2xN hv 2815.ifc \type, put 2816 add \sr2, \src, \s_strd 2817 add \ds2, \dst, \d_strd 2818 lsl \s_strd, \s_strd, #1 2819 lsl \d_strd, \d_strd, #1 2820 2821 vld1.32 {d28[]}, [\src], \s_strd 2822 vext.8 d29, d28, d28, #1 2823 vmull.u8 q8, d28, d0 2824 vmlal.u8 q8, d29, d1 2825 28262: 2827 vld1.32 {d28[]}, [\sr2], \s_strd 2828 vld1.32 {d30[]}, [\src], \s_strd 2829 vext.8 d29, d28, d28, #1 2830 vext.8 d31, d30, d30, #1 2831 vtrn.16 d28, d30 2832 vtrn.16 d29, d31 2833 vmull.u8 q9, d28, d0 2834 vmlal.u8 q9, d29, d1 2835 2836 vtrn.32 d16, d18 2837 2838 vmul.u16 d20, d16, d4 2839 vmla.u16 d20, d19, d6 2840 vqrshrn.u16 d20, q10, #8 2841 subs \h, \h, #2 2842 vst1.16 {d20[0]}, [\dst, :16], \d_strd 2843 vst1.16 {d20[1]}, [\ds2, :16], \d_strd 2844 ble 0f 2845 vtrn.32 d19, d16 2846 b 2b 28470: 2848 pop {r4-r11,pc} 2849.endif 2850 285140: // 4xN hv 2852 add \sr2, \src, \s_strd 2853 add \ds2, \dst, \d_strd 2854 lsl \s_strd, \s_strd, #1 2855 lsl \d_strd, \d_strd, #1 2856 2857 vld1.8 {d28}, [\src], \s_strd 2858 vext.8 d29, d28, d28, #1 2859 vmull.u8 q8, d28, d0 2860 vmlal.u8 q8, d29, d1 2861 28624: 2863 vld1.8 {d28}, [\sr2], \s_strd 2864 vld1.8 {d30}, [\src], \s_strd 2865 vext.8 d29, d28, d28, #1 2866 vext.8 d31, d30, d30, #1 2867 vtrn.32 d28, d30 2868 vtrn.32 d29, d31 2869 vmull.u8 q9, d28, d0 2870 vmlal.u8 q9, d29, d1 2871 2872 vmov d17, d18 2873 2874 vmul.u16 q10, q8, q2 2875 vmla.u16 q10, q9, q3 2876 subs \h, \h, #2 2877.ifc \type, put 2878 vqrshrn.u16 d20, q10, #8 2879 vst1.32 {d20[0]}, [\dst, :32], \d_strd 2880 vst1.32 {d20[1]}, [\ds2, :32], \d_strd 2881.else 2882 vrshr.u16 q10, q10, #4 2883 vst1.16 {d20}, [\dst, :64], \d_strd 2884 vst1.16 {d21}, [\ds2, :64], \d_strd 2885.endif 2886 ble 0f 2887 vmov d16, d19 2888 b 4b 28890: 2890 pop {r4-r11,pc} 2891 289280: // 8xN, 16xN, ... hv 2893160: 2894320: 2895640: 28961280: 2897 mov \my, \h 2898 28991: 2900 add \sr2, \src, \s_strd 2901 add \ds2, \dst, \d_strd 2902 lsl \s_strd, \s_strd, #1 2903 lsl \d_strd, \d_strd, #1 2904 2905 vld1.8 {q12}, [\src], \s_strd 2906 vext.8 q13, q12, q12, #1 2907 vmull.u8 q8, d24, d0 2908 vmlal.u8 q8, d26, d1 2909 29102: 2911 vld1.8 {q12}, [\sr2], \s_strd 2912 vld1.8 {q14}, [\src], \s_strd 2913 vext.8 q13, q12, q12, #1 2914 vext.8 q15, q14, q14, #1 2915 vmull.u8 q9, d24, d0 2916 vmlal.u8 q9, d26, d1 2917 vmull.u8 q10, d28, d0 2918 vmlal.u8 q10, d30, d1 2919 2920 vmul.u16 q8, q8, q2 2921 vmla.u16 q8, q9, q3 2922 vmul.u16 q9, q9, q2 2923 vmla.u16 q9, q10, q3 2924 subs \h, \h, #2 2925.ifc \type, put 2926 vqrshrn.u16 d16, q8, #8 2927 vqrshrn.u16 d18, q9, #8 2928 vst1.8 {d16}, [\dst, :64], \d_strd 2929 vst1.8 {d18}, [\ds2, :64], \d_strd 2930.else 2931 vrshr.u16 q8, q8, #4 2932 vrshr.u16 q9, q9, #4 2933 vst1.16 {q8}, [\dst, :128], \d_strd 2934 vst1.16 {q9}, [\ds2, :128], \d_strd 2935.endif 2936 ble 9f 2937 vmov q8, q10 2938 b 2b 29399: 2940 subs \w, \w, #8 2941 ble 0f 2942 asr \s_strd, \s_strd, #1 2943 asr \d_strd, \d_strd, #1 2944 mls \src, \s_strd, \my, \src 2945 mls \dst, \d_strd, \my, \dst 2946 sub \src, \src, \s_strd, lsl #1 2947 mov \h, \my 2948 add \src, \src, #8 2949.ifc \type, put 2950 add \dst, \dst, #8 2951.else 2952 add \dst, \dst, #16 2953.endif 2954 b 1b 29550: 2956 pop {r4-r11,pc} 2957endfunc 2958.endm 2959 2960filter_fn put, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, 10 2961filter_fn prep, r0, r7, r1, r2, r3, r4, r5, r6, r8, r9, 6 2962 2963.macro load_filter_ptr src 2964 asr r12, \src, #10 2965 add r12, r11, r12, lsl #3 2966.endm 2967 2968.macro load_filter_coef dst, src, inc 2969 add \src, \src, \inc 2970 vld1.8 {\dst}, [r12, :64] 2971.endm 2972 2973.macro load_filter_row dst, src, inc 2974 load_filter_ptr \src 2975 load_filter_coef \dst, \src, \inc 2976.endm 2977 2978function warp_filter_horz_neon 2979 load_filter_ptr r5 // filter 0 2980 vld1.16 {q7}, [r2], r3 2981 vmov.i8 q6, #128 2982 2983 load_filter_coef d0, r5, r7 // filter 0 2984 load_filter_row d1, r5, r7 // filter 1 2985 load_filter_row d2, r5, r7 // filter 2 2986 load_filter_ptr r5 // filter 3 2987 veor q7, q7, q6 // subtract by 128 to allow using vmull 2988 load_filter_coef d3, r5, r7 // filter 3 2989 vext.8 d12, d14, d15, #1 // filter 1 pixels 2990 vext.8 d13, d14, d15, #2 // filter 2 pixels 2991 load_filter_ptr r5 // filter 4 2992 vmull.s8 q2, d14, d0 // filter 0 output 2993 vmull.s8 q3, d12, d1 // filter 1 output 2994 load_filter_coef d0, r5, r7 // filter 4 2995 load_filter_ptr r5 // filter 5 2996 vext.8 d12, d14, d15, #3 // filter 3 pixels 2997 vmull.s8 q4, d13, d2 // filter 2 output 2998 vext.8 d13, d14, d15, #4 // filter 4 pixels 2999 vpadd.i16 d4, d4, d5 // pixel 0 (4x16) 3000 vpadd.i16 d5, d6, d7 // pixel 1 (4x16) 3001 load_filter_coef d1, r5, r7 // filter 5 3002 load_filter_ptr r5 // filter 6 3003 vmull.s8 q5, d12, d3 // filter 3 output 3004 vext.8 d12, d14, d15, #5 // filter 5 pixels 3005 vmull.s8 q3, d13, d0 // filter 4 output 3006 load_filter_coef d0, r5, r7 // filter 6 3007 vext.8 d13, d14, d15, #6 // filter 6 pixels 3008 load_filter_ptr r5 // filter 7 3009 vpadd.i16 d8, d8, d9 // pixel 2 (4x16) 3010 vpadd.i16 d9, d10, d11 // pixel 3 (4x16) 3011 vmull.s8 q5, d12, d1 // filter 5 output 3012 load_filter_coef d1, r5, r7 // filter 7 3013 vext.8 d14, d14, d15, #7 // filter 7 pixels 3014 vpadd.i16 d6, d6, d7 // pixel 4 (4x16) 3015 vpadd.i16 d10, d10, d11 // pixel 5 (4x16) 3016 vmull.s8 q6, d13, d0 // filter 6 output 3017 vmull.s8 q7, d14, d1 // filter 7 output 3018 3019 sub r5, r5, r7, lsl #3 3020 3021 vpadd.i16 d4, d4, d5 // pixel 0,1 (2x16) 3022 vpadd.i16 d5, d8, d9 // pixel 2,3 (2x16) 3023 vpadd.i16 d12, d12, d13 // pixel 6 (4x16) 3024 vpadd.i16 d14, d14, d15 // pixel 7 (4x16) 3025 vpadd.i16 d6, d6, d10 // pixel 4,5 (2x16) 3026 vpadd.i16 d10, d12, d14 // pixel 6,7 (2x16) 3027 vpadd.i16 d4, d4, d5 // pixel 0-3 3028 vpadd.i16 d5, d6, d10 // pixel 4-7 3029 3030 add r5, r5, r8 3031 3032 bx lr 3033endfunc 3034 3035// void dav1d_warp_affine_8x8_8bpc_neon( 3036// pixel *dst, const ptrdiff_t dst_stride, 3037// const pixel *src, const ptrdiff_t src_stride, 3038// const int16_t *const abcd, int mx, int my) 3039.macro warp t, shift 3040function warp_affine_8x8\t\()_8bpc_neon, export=1 3041 push {r4-r11,lr} 3042 vpush {q4-q7} 3043 ldrd r4, r5, [sp, #100] 3044 ldr r6, [sp, #108] 3045 ldrd r8, r9, [r4] 3046 sxth r7, r8 3047 asr r8, r8, #16 3048 asr r4, r9, #16 3049 sxth r9, r9 3050 mov r10, #8 3051 sub r2, r2, r3, lsl #1 3052 sub r2, r2, r3 3053 sub r2, r2, #3 3054 movrel r11, X(mc_warp_filter), 64*8 3055.ifnb \t 3056 lsl r1, r1, #1 3057.endif 3058 add r5, r5, #512 3059 add r6, r6, #512 3060 3061 bl warp_filter_horz_neon 3062 vrshr.s16 q8, q2, #3 3063 bl warp_filter_horz_neon 3064 vrshr.s16 q9, q2, #3 3065 bl warp_filter_horz_neon 3066 vrshr.s16 q10, q2, #3 3067 bl warp_filter_horz_neon 3068 vrshr.s16 q11, q2, #3 3069 bl warp_filter_horz_neon 3070 vrshr.s16 q12, q2, #3 3071 bl warp_filter_horz_neon 3072 vrshr.s16 q13, q2, #3 3073 bl warp_filter_horz_neon 3074 vrshr.s16 q14, q2, #3 3075 30761: 3077 bl warp_filter_horz_neon 3078 vrshr.s16 q15, q2, #3 3079 3080 load_filter_row d8, r6, r9 3081 load_filter_row d9, r6, r9 3082 load_filter_row d10, r6, r9 3083 load_filter_row d11, r6, r9 3084 load_filter_row d12, r6, r9 3085 load_filter_row d13, r6, r9 3086 load_filter_row d14, r6, r9 3087 load_filter_row d15, r6, r9 3088 transpose_8x8b q4, q5, q6, q7, d8, d9, d10, d11, d12, d13, d14, d15 3089 vmovl.s8 q1, d8 3090 vmovl.s8 q2, d9 3091 vmovl.s8 q3, d10 3092 vmovl.s8 q4, d11 3093 vmovl.s8 q5, d12 3094 vmovl.s8 q6, d13 3095 3096 sub r6, r6, r9, lsl #3 3097 3098 // This ordering of vmull/vmlal is highly beneficial for 3099 // Cortex A8/A9/A53 here, but harmful for Cortex A7. 3100 vmull.s16 q0, d16, d2 3101 vmlal.s16 q0, d18, d4 3102 vmlal.s16 q0, d20, d6 3103 vmlal.s16 q0, d22, d8 3104 vmlal.s16 q0, d24, d10 3105 vmlal.s16 q0, d26, d12 3106 vmull.s16 q1, d17, d3 3107 vmlal.s16 q1, d19, d5 3108 vmlal.s16 q1, d21, d7 3109 vmlal.s16 q1, d23, d9 3110 vmlal.s16 q1, d25, d11 3111 vmlal.s16 q1, d27, d13 3112 3113 vmovl.s8 q2, d14 3114 vmovl.s8 q3, d15 3115 3116 vmlal.s16 q0, d28, d4 3117 vmlal.s16 q0, d30, d6 3118 vmlal.s16 q1, d29, d5 3119 vmlal.s16 q1, d31, d7 3120 3121.ifb \t 3122 vmov.i16 q7, #128 3123.else 3124 vmov.i16 q7, #0x800 3125.endif 3126 3127 vmov q8, q9 3128 vmov q9, q10 3129 vqrshrn.s32 d0, q0, #\shift 3130 vmov q10, q11 3131 vqrshrn.s32 d1, q1, #\shift 3132 vmov q11, q12 3133 vadd.i16 q0, q0, q7 3134 vmov q12, q13 3135.ifb \t 3136 vqmovun.s16 d0, q0 3137.endif 3138 vmov q13, q14 3139 vmov q14, q15 3140 subs r10, r10, #1 3141.ifnb \t 3142 vst1.16 {q0}, [r0, :128], r1 3143.else 3144 vst1.8 {d0}, [r0, :64], r1 3145.endif 3146 3147 add r6, r6, r4 3148 bgt 1b 3149 3150 vpop {q4-q7} 3151 pop {r4-r11,pc} 3152endfunc 3153.endm 3154 3155warp , 11 3156warp t, 7 3157 3158// void dav1d_emu_edge_8bpc_neon( 3159// const intptr_t bw, const intptr_t bh, 3160// const intptr_t iw, const intptr_t ih, 3161// const intptr_t x, const intptr_t y, 3162// pixel *dst, const ptrdiff_t dst_stride, 3163// const pixel *ref, const ptrdiff_t ref_stride) 3164function emu_edge_8bpc_neon, export=1 3165 push {r4-r11,lr} 3166 ldrd r4, r5, [sp, #36] 3167 ldrd r6, r7, [sp, #44] 3168 ldrd r8, r9, [sp, #52] 3169 3170 // ref += iclip(y, 0, ih - 1) * PXSTRIDE(ref_stride) 3171 // ref += iclip(x, 0, iw - 1) 3172 sub r12, r3, #1 // ih - 1 3173 cmp r5, r3 3174 sub lr, r2, #1 // iw - 1 3175 it lt 3176 movlt r12, r5 // min(y, ih - 1) 3177 cmp r4, r2 3178 bic r12, r12, r12, asr #31 // max(min(y, ih - 1), 0) 3179 it lt 3180 movlt lr, r4 // min(x, iw - 1) 3181 bic lr, lr, lr, asr #31 // max(min(x, iw - 1), 0) 3182 mla r8, r12, r9, r8 // ref += iclip() * stride 3183 add r8, r8, lr // ref += iclip() 3184 3185 // bottom_ext = iclip(y + bh - ih, 0, bh - 1) 3186 // top_ext = iclip(-y, 0, bh - 1) 3187 add r10, r5, r1 // y + bh 3188 neg r5, r5 // -y 3189 sub r10, r10, r3 // y + bh - ih 3190 sub r12, r1, #1 // bh - 1 3191 cmp r10, r1 3192 bic r5, r5, r5, asr #31 // max(-y, 0) 3193 it ge 3194 movge r10, r12 // min(y + bh - ih, bh-1) 3195 cmp r5, r1 3196 bic r10, r10, r10, asr #31 // max(min(y + bh - ih, bh-1), 0) 3197 it ge 3198 movge r5, r12 // min(max(-y, 0), bh-1) 3199 3200 // right_ext = iclip(x + bw - iw, 0, bw - 1) 3201 // left_ext = iclip(-x, 0, bw - 1) 3202 add r11, r4, r0 // x + bw 3203 neg r4, r4 // -x 3204 sub r11, r11, r2 // x + bw - iw 3205 sub lr, r0, #1 // bw - 1 3206 cmp r11, r0 3207 bic r4, r4, r4, asr #31 // max(-x, 0) 3208 it ge 3209 movge r11, lr // min(x + bw - iw, bw-1) 3210 cmp r4, r0 3211 bic r11, r11, r11, asr #31 // max(min(x + bw - iw, bw-1), 0) 3212 it ge 3213 movge r4, lr // min(max(-x, 0), bw - 1) 3214 3215 // center_h = bh - top_ext - bottom_ext 3216 // dst += top_ext * PXSTRIDE(dst_stride) 3217 // center_w = bw - left_ext - right_ext 3218 sub r1, r1, r5 // bh - top_ext 3219 mla r6, r5, r7, r6 3220 sub r2, r0, r4 // bw - left_ext 3221 sub r1, r1, r10 // center_h = bh - top_ext - bottom_ext 3222 sub r2, r2, r11 // center_w = bw - left_ext - right_ext 3223 3224 mov r0, r6 // backup of dst 3225 3226.macro v_loop need_left, need_right 32270: 3228.if \need_left 3229 vld1.8 {d0[], d1[]}, [r8] 3230 mov r12, r6 // out = dst 3231 mov r3, r4 32321: 3233 subs r3, r3, #16 3234 vst1.8 {q0}, [r12, :128]! 3235 bgt 1b 3236.endif 3237 mov lr, r8 3238 add r12, r6, r4 // out = dst + left_ext 3239 mov r3, r2 32401: 3241 vld1.8 {q0, q1}, [lr]! 3242 subs r3, r3, #32 3243.if \need_left 3244 vst1.8 {q0, q1}, [r12]! 3245.else 3246 vst1.8 {q0, q1}, [r12, :128]! 3247.endif 3248 bgt 1b 3249.if \need_right 3250 add r3, r8, r2 // in + center_w 3251 sub r3, r3, #1 // in + center_w - 1 3252 add r12, r6, r4 // dst + left_ext 3253 vld1.8 {d0[], d1[]}, [r3] 3254 add r12, r12, r2 // out = dst + left_ext + center_w 3255 mov r3, r11 32561: 3257 subs r3, r3, #16 3258 vst1.8 {q0}, [r12]! 3259 bgt 1b 3260.endif 3261 3262 subs r1, r1, #1 // center_h-- 3263 add r6, r6, r7 3264 add r8, r8, r9 3265 bgt 0b 3266.endm 3267 3268 cmp r4, #0 3269 beq 2f 3270 // need_left 3271 cmp r11, #0 3272 beq 3f 3273 // need_left + need_right 3274 v_loop 1, 1 3275 b 5f 3276 32772: 3278 // !need_left 3279 cmp r11, #0 3280 beq 4f 3281 // !need_left + need_right 3282 v_loop 0, 1 3283 b 5f 3284 32853: 3286 // need_left + !need_right 3287 v_loop 1, 0 3288 b 5f 3289 32904: 3291 // !need_left + !need_right 3292 v_loop 0, 0 3293 32945: 3295 cmp r10, #0 3296 // Storing the original dst in r0 overwrote bw, recalculate it here 3297 add r2, r2, r4 // center_w + left_ext 3298 add r2, r2, r11 // bw = center_w + left_ext + right_ext 3299 3300 beq 3f 3301 // need_bottom 3302 sub r8, r6, r7 // ref = dst - stride 3303 mov r4, r2 33041: 3305 vld1.8 {q0, q1}, [r8, :128]! 3306 mov r3, r10 33072: 3308 subs r3, r3, #1 3309 vst1.8 {q0, q1}, [r6, :128], r7 3310 bgt 2b 3311 mls r6, r7, r10, r6 // dst -= bottom_ext * stride 3312 subs r4, r4, #32 // bw -= 32 3313 add r6, r6, #32 // dst += 32 3314 bgt 1b 3315 33163: 3317 cmp r5, #0 3318 beq 3f 3319 // need_top 3320 mls r6, r7, r5, r0 // dst = stored_dst - top_ext * stride 33211: 3322 vld1.8 {q0, q1}, [r0, :128]! 3323 mov r3, r5 33242: 3325 subs r3, r3, #1 3326 vst1.8 {q0, q1}, [r6, :128], r7 3327 bgt 2b 3328 mls r6, r7, r5, r6 // dst -= top_ext * stride 3329 subs r2, r2, #32 // bw -= 32 3330 add r6, r6, #32 // dst += 32 3331 bgt 1b 3332 33333: 3334 pop {r4-r11,pc} 3335endfunc 3336