1/* 2 * Copyright © 2018, VideoLAN and dav1d authors 3 * Copyright © 2019, B Krishnan Iyer 4 * Copyright © 2020, Martin Storsjo 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright notice, this 11 * list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29#include "src/arm/asm.S" 30#include "util.S" 31 32// void ipred_dc_128_16bpc_neon(pixel *dst, const ptrdiff_t stride, 33// const pixel *const topleft, 34// const int width, const int height, const int a, 35// const int max_width, const int max_height, 36// const int bitdepth_max); 37function ipred_dc_128_16bpc_neon, export=1 38 push {r4, lr} 39 ldr r4, [sp, #8] 40 ldr r12, [sp, #24] 41 clz r3, r3 42 adr r2, L(ipred_dc_128_tbl) 43 sub r3, r3, #25 44 vdup.16 q0, r12 45 ldr r3, [r2, r3, lsl #2] 46 add r12, r0, r1 47 vrshr.u16 q0, q0, #1 48 add r2, r2, r3 49 lsl r1, r1, #1 50 bx r2 51 52 .align 2 53L(ipred_dc_128_tbl): 54 .word 640f - L(ipred_dc_128_tbl) + CONFIG_THUMB 55 .word 320f - L(ipred_dc_128_tbl) + CONFIG_THUMB 56 .word 160f - L(ipred_dc_128_tbl) + CONFIG_THUMB 57 .word 8f - L(ipred_dc_128_tbl) + CONFIG_THUMB 58 .word 4f - L(ipred_dc_128_tbl) + CONFIG_THUMB 594: 60 vst1.16 {d0}, [r0, :64], r1 61 vst1.16 {d0}, [r12, :64], r1 62 subs r4, r4, #4 63 vst1.16 {d0}, [r0, :64], r1 64 vst1.16 {d0}, [r12, :64], r1 65 bgt 4b 66 pop {r4, pc} 678: 68 vst1.16 {d0, d1}, [r0, :128], r1 69 vst1.16 {d0, d1}, [r12, :128], r1 70 subs r4, r4, #4 71 vst1.16 {d0, d1}, [r0, :128], r1 72 vst1.16 {d0, d1}, [r12, :128], r1 73 bgt 8b 74 pop {r4, pc} 75160: 76 vmov q1, q0 7716: 78 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 79 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 80 subs r4, r4, #4 81 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 82 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 83 bgt 16b 84 pop {r4, pc} 85320: 86 vmov q1, q0 87 sub r1, r1, #32 8832: 89 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 90 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 91 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 92 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 93 subs r4, r4, #4 94 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 95 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 96 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 97 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 98 bgt 32b 99 pop {r4, pc} 100640: 101 vmov q1, q0 102 sub r1, r1, #96 10364: 104 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 105 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 106 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 107 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 108 subs r4, r4, #2 109 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 110 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 111 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 112 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 113 bgt 64b 114 pop {r4, pc} 115endfunc 116 117// void ipred_v_16bpc_neon(pixel *dst, const ptrdiff_t stride, 118// const pixel *const topleft, 119// const int width, const int height, const int a, 120// const int max_width, const int max_height); 121function ipred_v_16bpc_neon, export=1 122 push {r4, lr} 123 ldr lr, [sp, #8] 124 clz r3, r3 125 adr r4, L(ipred_v_tbl) 126 sub r3, r3, #25 127 ldr r3, [r4, r3, lsl #2] 128 add r2, r2, #2 129 add r4, r4, r3 130 add r12, r0, r1 131 lsl r1, r1, #1 132 bx r4 133 134 .align 2 135L(ipred_v_tbl): 136 .word 640f - L(ipred_v_tbl) + CONFIG_THUMB 137 .word 320f - L(ipred_v_tbl) + CONFIG_THUMB 138 .word 160f - L(ipred_v_tbl) + CONFIG_THUMB 139 .word 80f - L(ipred_v_tbl) + CONFIG_THUMB 140 .word 40f - L(ipred_v_tbl) + CONFIG_THUMB 141 14240: 143 vld1.16 {d0}, [r2] 1444: 145 vst1.16 {d0}, [r0, :64], r1 146 vst1.16 {d0}, [r12, :64], r1 147 subs lr, lr, #4 148 vst1.16 {d0}, [r0, :64], r1 149 vst1.16 {d0}, [r12, :64], r1 150 bgt 4b 151 pop {r4, pc} 15280: 153 vld1.16 {q0}, [r2] 1548: 155 vst1.16 {d0, d1}, [r0, :128], r1 156 vst1.16 {d0, d1}, [r12, :128], r1 157 subs lr, lr, #4 158 vst1.16 {d0, d1}, [r0, :128], r1 159 vst1.16 {d0, d1}, [r12, :128], r1 160 bgt 8b 161 pop {r4, pc} 162160: 163 vld1.16 {q0, q1}, [r2] 16416: 165 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 166 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 167 subs lr, lr, #4 168 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 169 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 170 bgt 16b 171 pop {r4, pc} 172320: 173 vld1.16 {q0, q1}, [r2]! 174 sub r1, r1, #32 175 vld1.16 {q2, q3}, [r2] 17632: 177 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 178 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 179 vst1.16 {d4, d5, d6, d7}, [r0, :128], r1 180 vst1.16 {d4, d5, d6, d7}, [r12, :128], r1 181 subs lr, lr, #4 182 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 183 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 184 vst1.16 {d4, d5, d6, d7}, [r0, :128], r1 185 vst1.16 {d4, d5, d6, d7}, [r12, :128], r1 186 bgt 32b 187 pop {r4, pc} 188640: 189 vld1.16 {q0, q1}, [r2]! 190 sub r1, r1, #96 191 vld1.16 {q2, q3}, [r2]! 192 vld1.16 {q8, q9}, [r2]! 193 vld1.16 {q10, q11}, [r2]! 19464: 195 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 196 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 197 vst1.16 {d4, d5, d6, d7}, [r0, :128]! 198 vst1.16 {d4, d5, d6, d7}, [r12, :128]! 199 subs lr, lr, #2 200 vst1.16 {d16, d17, d18, d19}, [r0, :128]! 201 vst1.16 {d16, d17, d18, d19}, [r12, :128]! 202 vst1.16 {d20, d21, d22, d23}, [r0, :128], r1 203 vst1.16 {d20, d21, d22, d23}, [r12, :128], r1 204 bgt 64b 205 pop {r4, pc} 206endfunc 207 208// void ipred_h_16bpc_neon(pixel *dst, const ptrdiff_t stride, 209// const pixel *const topleft, 210// const int width, const int height, const int a, 211// const int max_width, const int max_height); 212function ipred_h_16bpc_neon, export=1 213 push {r4-r5, lr} 214 ldr r4, [sp, #12] 215 clz r3, r3 216 adr r5, L(ipred_h_tbl) 217 sub r3, r3, #25 218 ldr r3, [r5, r3, lsl #2] 219 sub r2, r2, #2 220 mov lr, #-2 221 add r5, r5, r3 222 add r12, r0, r1 223 lsl r1, r1, #1 224 bx r5 225 226 .align 2 227L(ipred_h_tbl): 228 .word 640f - L(ipred_h_tbl) + CONFIG_THUMB 229 .word 320f - L(ipred_h_tbl) + CONFIG_THUMB 230 .word 160f - L(ipred_h_tbl) + CONFIG_THUMB 231 .word 8f - L(ipred_h_tbl) + CONFIG_THUMB 232 .word 40f - L(ipred_h_tbl) + CONFIG_THUMB 23340: 234 sub r2, r2, #6 235 mov lr, #-8 2364: 237 vld4.16 {d0[], d1[], d2[], d3[]}, [r2], lr 238 vst1.16 {d3}, [r0, :64], r1 239 vst1.16 {d2}, [r12, :64], r1 240 subs r4, r4, #4 241 vst1.16 {d1}, [r0, :64], r1 242 vst1.16 {d0}, [r12, :64], r1 243 bgt 4b 244 pop {r4-r5, pc} 2458: 246 vld1.16 {d0[], d1[]}, [r2], lr 247 subs r4, r4, #4 248 vld1.16 {d2[], d3[]}, [r2], lr 249 vst1.16 {q0}, [r0, :128], r1 250 vld1.16 {d4[], d5[]}, [r2], lr 251 vst1.16 {q1}, [r12, :128], r1 252 vld1.16 {d6[], d7[]}, [r2], lr 253 vst1.16 {q2}, [r0, :128], r1 254 vst1.16 {q3}, [r12, :128], r1 255 bgt 8b 256 pop {r4-r5, pc} 257160: 258 sub r1, r1, #16 25916: 260 vld1.16 {d0[], d1[]}, [r2], lr 261 subs r4, r4, #4 262 vld1.16 {d2[], d3[]}, [r2], lr 263 vst1.16 {q0}, [r0, :128]! 264 vld1.16 {d4[], d5[]}, [r2], lr 265 vst1.16 {q1}, [r12, :128]! 266 vld1.16 {d6[], d7[]}, [r2], lr 267 vst1.16 {q0}, [r0, :128], r1 268 vst1.16 {q1}, [r12, :128], r1 269 vst1.16 {q2}, [r0, :128]! 270 vst1.16 {q3}, [r12, :128]! 271 vst1.16 {q2}, [r0, :128], r1 272 vst1.16 {q3}, [r12, :128], r1 273 bgt 16b 274 pop {r4-r5, pc} 275320: 276 sub r1, r1, #48 27732: 278 vld1.16 {d0[], d1[]}, [r2], lr 279 subs r4, r4, #4 280 vld1.16 {d2[], d3[]}, [r2], lr 281 vst1.16 {q0}, [r0, :128]! 282 vld1.16 {d4[], d5[]}, [r2], lr 283 vst1.16 {q1}, [r12, :128]! 284 vld1.16 {d6[], d7[]}, [r2], lr 285 vst1.16 {q0}, [r0, :128]! 286 vst1.16 {q1}, [r12, :128]! 287 vst1.16 {q0}, [r0, :128]! 288 vst1.16 {q1}, [r12, :128]! 289 vst1.16 {q0}, [r0, :128], r1 290 vst1.16 {q1}, [r12, :128], r1 291 vst1.16 {q2}, [r0, :128]! 292 vst1.16 {q3}, [r12, :128]! 293 vst1.16 {q2}, [r0, :128]! 294 vst1.16 {q3}, [r12, :128]! 295 vst1.16 {q2}, [r0, :128]! 296 vst1.16 {q3}, [r12, :128]! 297 vst1.16 {q2}, [r0, :128], r1 298 vst1.16 {q3}, [r12, :128], r1 299 bgt 32b 300 pop {r4-r5, pc} 301640: 302 sub r1, r1, #96 30364: 304 vld1.16 {d0[], d1[]}, [r2], lr 305 subs r4, r4, #2 306 vld1.16 {d4[], d5[]}, [r2], lr 307 vmov q1, q0 308 vmov q3, q2 309 vst1.16 {q0, q1}, [r0, :128]! 310 vst1.16 {q2, q3}, [r12, :128]! 311 vst1.16 {q0, q1}, [r0, :128]! 312 vst1.16 {q2, q3}, [r12, :128]! 313 vst1.16 {q0, q1}, [r0, :128]! 314 vst1.16 {q2, q3}, [r12, :128]! 315 vst1.16 {q0, q1}, [r0, :128], r1 316 vst1.16 {q2, q3}, [r12, :128], r1 317 bgt 64b 318 pop {r4-r5, pc} 319endfunc 320 321// void ipred_dc_top_16bpc_neon(pixel *dst, const ptrdiff_t stride, 322// const pixel *const topleft, 323// const int width, const int height, const int a, 324// const int max_width, const int max_height); 325function ipred_dc_top_16bpc_neon, export=1 326 push {r4-r5, lr} 327 ldr r4, [sp, #12] 328 clz r3, r3 329 adr r5, L(ipred_dc_top_tbl) 330 sub r3, r3, #25 331 ldr r3, [r5, r3, lsl #2] 332 add r2, r2, #2 333 add r5, r5, r3 334 add r12, r0, r1 335 lsl r1, r1, #1 336 bx r5 337 338 .align 2 339L(ipred_dc_top_tbl): 340 .word 640f - L(ipred_dc_top_tbl) + CONFIG_THUMB 341 .word 320f - L(ipred_dc_top_tbl) + CONFIG_THUMB 342 .word 160f - L(ipred_dc_top_tbl) + CONFIG_THUMB 343 .word 80f - L(ipred_dc_top_tbl) + CONFIG_THUMB 344 .word 40f - L(ipred_dc_top_tbl) + CONFIG_THUMB 345 34640: 347 vld1.16 {d0}, [r2] 348 vpadd.i16 d0, d0, d0 349 vpadd.i16 d0, d0, d0 350 vrshr.u16 d0, d0, #2 351 vdup.16 d0, d0[0] 3524: 353 vst1.16 {d0}, [r0, :64], r1 354 vst1.16 {d0}, [r12, :64], r1 355 subs r4, r4, #4 356 vst1.16 {d0}, [r0, :64], r1 357 vst1.16 {d0}, [r12, :64], r1 358 bgt 4b 359 pop {r4-r5, pc} 36080: 361 vld1.16 {d0, d1}, [r2] 362 vadd.i16 d0, d0, d1 363 vpadd.i16 d0, d0, d0 364 vpadd.i16 d0, d0, d0 365 vrshr.u16 d0, d0, #3 366 vdup.16 q0, d0[0] 3678: 368 vst1.16 {d0, d1}, [r0, :128], r1 369 vst1.16 {d0, d1}, [r12, :128], r1 370 subs r4, r4, #4 371 vst1.16 {d0, d1}, [r0, :128], r1 372 vst1.16 {d0, d1}, [r12, :128], r1 373 bgt 8b 374 pop {r4-r5, pc} 375160: 376 vld1.16 {d0, d1, d2, d3}, [r2] 377 vadd.i16 q0, q0, q1 378 vadd.i16 d0, d0, d1 379 vpadd.i16 d0, d0, d0 380 vpadd.i16 d0, d0, d0 381 vrshr.u16 d4, d0, #4 382 vdup.16 q0, d4[0] 383 vdup.16 q1, d4[0] 38416: 385 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 386 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 387 subs r4, r4, #4 388 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 389 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 390 bgt 16b 391 pop {r4-r5, pc} 392320: 393 vld1.16 {d0, d1, d2, d3}, [r2]! 394 vld1.16 {d4, d5, d6, d7}, [r2] 395 vadd.i16 q0, q0, q1 396 vadd.i16 q2, q2, q3 397 vadd.i16 q0, q0, q2 398 vadd.i16 d0, d0, d1 399 vpadd.i16 d0, d0, d0 400 vpaddl.u16 d0, d0 401 vrshrn.i32 d18, q0, #5 402 vdup.16 q0, d18[0] 403 vdup.16 q1, d18[0] 404 sub r1, r1, #32 40532: 406 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 407 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 408 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 409 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 410 subs r4, r4, #4 411 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 412 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 413 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 414 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 415 bgt 32b 416 pop {r4-r5, pc} 417640: 418 vld1.16 {d0, d1, d2, d3}, [r2]! 419 vld1.16 {d4, d5, d6, d7}, [r2]! 420 vadd.i16 q0, q0, q1 421 vld1.16 {d16, d17, d18, d19}, [r2]! 422 vadd.i16 q2, q2, q3 423 vld1.16 {d20, d21, d22, d23}, [r2] 424 vadd.i16 q8, q8, q9 425 vadd.i16 q10, q10, q11 426 vadd.i16 q0, q0, q2 427 vadd.i16 q8, q8, q10 428 vadd.i16 q0, q0, q8 429 vadd.i16 d0, d0, d1 430 vpaddl.u16 d0, d0 431 vpadd.i32 d0, d0, d0 432 vrshrn.i32 d18, q0, #6 433 vdup.16 q0, d18[0] 434 vdup.16 q1, d18[0] 435 sub r1, r1, #96 43664: 437 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 438 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 439 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 440 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 441 subs r4, r4, #2 442 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 443 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 444 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 445 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 446 bgt 64b 447 pop {r4-r5, pc} 448endfunc 449 450// void ipred_dc_left_16bpc_neon(pixel *dst, const ptrdiff_t stride, 451// const pixel *const topleft, 452// const int width, const int height, const int a, 453// const int max_width, const int max_height); 454function ipred_dc_left_16bpc_neon, export=1 455 push {r4-r5, lr} 456 ldr r4, [sp, #12] 457 sub r2, r2, r4, lsl #1 458 clz r3, r3 459 clz lr, r4 460 sub lr, lr, #25 461 adr r5, L(ipred_dc_left_tbl) 462 sub r3, r3, #20 463 ldr r3, [r5, r3, lsl #2] 464 ldr lr, [r5, lr, lsl #2] 465 add r3, r5, r3 466 add r5, r5, lr 467 add r12, r0, r1 468 lsl r1, r1, #1 469 bx r5 470 471 .align 2 472L(ipred_dc_left_tbl): 473 .word L(ipred_dc_left_h64) - L(ipred_dc_left_tbl) + CONFIG_THUMB 474 .word L(ipred_dc_left_h32) - L(ipred_dc_left_tbl) + CONFIG_THUMB 475 .word L(ipred_dc_left_h16) - L(ipred_dc_left_tbl) + CONFIG_THUMB 476 .word L(ipred_dc_left_h8) - L(ipred_dc_left_tbl) + CONFIG_THUMB 477 .word L(ipred_dc_left_h4) - L(ipred_dc_left_tbl) + CONFIG_THUMB 478 .word L(ipred_dc_left_w64) - L(ipred_dc_left_tbl) + CONFIG_THUMB 479 .word L(ipred_dc_left_w32) - L(ipred_dc_left_tbl) + CONFIG_THUMB 480 .word L(ipred_dc_left_w16) - L(ipred_dc_left_tbl) + CONFIG_THUMB 481 .word L(ipred_dc_left_w8) - L(ipred_dc_left_tbl) + CONFIG_THUMB 482 .word L(ipred_dc_left_w4) - L(ipred_dc_left_tbl) + CONFIG_THUMB 483 484L(ipred_dc_left_h4): 485 vld1.16 {d0}, [r2, :64] 486 vpadd.i16 d0, d0, d0 487 vpadd.i16 d0, d0, d0 488 vrshr.u16 d0, d0, #2 489 vdup.16 q0, d0[0] 490 bx r3 491L(ipred_dc_left_w4): 492 vst1.16 {d0}, [r0, :64], r1 493 vst1.16 {d0}, [r12, :64], r1 494 subs r4, r4, #4 495 vst1.16 {d0}, [r0, :64], r1 496 vst1.16 {d0}, [r12, :64], r1 497 bgt L(ipred_dc_left_w4) 498 pop {r4-r5, pc} 499L(ipred_dc_left_h8): 500 vld1.16 {d0, d1}, [r2, :128] 501 vadd.i16 d0, d0, d1 502 vpadd.i16 d0, d0, d0 503 vpadd.i16 d0, d0, d0 504 vrshr.u16 d0, d0, #3 505 vdup.16 q0, d0[0] 506 bx r3 507L(ipred_dc_left_w8): 508 vst1.16 {d0, d1}, [r0, :128], r1 509 vst1.16 {d0, d1}, [r12, :128], r1 510 subs r4, r4, #4 511 vst1.16 {d0, d1}, [r0, :128], r1 512 vst1.16 {d0, d1}, [r12, :128], r1 513 bgt L(ipred_dc_left_w8) 514 pop {r4-r5, pc} 515L(ipred_dc_left_h16): 516 vld1.16 {d0, d1, d2, d3}, [r2, :128] 517 vadd.i16 q0, q0, q1 518 vadd.i16 d0, d0, d1 519 vpadd.i16 d0, d0, d0 520 vpadd.i16 d0, d0, d0 521 vrshr.u16 d0, d0, #4 522 vdup.16 q0, d0[0] 523 bx r3 524L(ipred_dc_left_w16): 525 vmov q1, q0 5261: 527 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 528 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 529 subs r4, r4, #4 530 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 531 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 532 bgt 1b 533 pop {r4-r5, pc} 534L(ipred_dc_left_h32): 535 vld1.16 {d0, d1, d2, d3}, [r2, :128]! 536 vld1.16 {d4, d5, d6, d7}, [r2, :128] 537 vadd.i16 q0, q0, q1 538 vadd.i16 q2, q2, q3 539 vadd.i16 q0, q0, q2 540 vadd.i16 d0, d0, d1 541 vpadd.i16 d0, d0, d0 542 vpaddl.u16 d0, d0 543 vrshrn.i32 d0, q0, #5 544 vdup.16 q0, d0[0] 545 bx r3 546L(ipred_dc_left_w32): 547 sub r1, r1, #32 548 vmov q1, q0 5491: 550 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 551 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 552 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 553 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 554 subs r4, r4, #4 555 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 556 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 557 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 558 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 559 bgt 1b 560 pop {r4-r5, pc} 561L(ipred_dc_left_h64): 562 vld1.16 {d0, d1, d2, d3}, [r2, :128]! 563 vld1.16 {d4, d5, d6, d7}, [r2, :128]! 564 vadd.i16 q0, q0, q1 565 vld1.16 {d16, d17, d18, d19}, [r2, :128]! 566 vadd.i16 q2, q2, q3 567 vld1.16 {d20, d21, d22, d23}, [r2, :128] 568 vadd.i16 q8, q8, q9 569 vadd.i16 q10, q10, q11 570 vadd.i16 q0, q0, q2 571 vadd.i16 q8, q8, q10 572 vadd.i16 q0, q0, q8 573 vadd.i16 d0, d0, d1 574 vpaddl.u16 d0, d0 575 vpadd.i32 d0, d0, d0 576 vrshrn.i32 d0, q0, #6 577 vdup.16 q0, d0[0] 578 bx r3 579L(ipred_dc_left_w64): 580 sub r1, r1, #96 581 vmov q1, q0 5821: 583 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 584 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 585 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 586 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 587 subs r4, r4, #2 588 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 589 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 590 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 591 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 592 bgt 1b 593 pop {r4-r5, pc} 594endfunc 595 596// void ipred_dc_16bpc_neon(pixel *dst, const ptrdiff_t stride, 597// const pixel *const topleft, 598// const int width, const int height, const int a, 599// const int max_width, const int max_height); 600function ipred_dc_16bpc_neon, export=1 601 push {r4-r6, lr} 602 ldr r4, [sp, #16] 603 sub r2, r2, r4, lsl #1 604 add lr, r3, r4 // width + height 605 clz r3, r3 606 clz r12, r4 607 vdup.32 q15, lr // width + height 608 adr r5, L(ipred_dc_tbl) 609 rbit lr, lr // rbit(width + height) 610 sub r3, r3, #20 // 25 leading bits, minus table offset 5 611 sub r12, r12, #25 612 clz lr, lr // ctz(width + height) 613 ldr r3, [r5, r3, lsl #2] 614 ldr r12, [r5, r12, lsl #2] 615 neg lr, lr // -ctz(width + height) 616 add r3, r5, r3 617 add r5, r5, r12 618 vshr.u32 q15, q15, #1 // (width + height) >> 1 619 vdup.32 q14, lr // -ctz(width + height) 620 add r12, r0, r1 621 lsl r1, r1, #1 622 bx r5 623 624 .align 2 625L(ipred_dc_tbl): 626 .word L(ipred_dc_h64) - L(ipred_dc_tbl) + CONFIG_THUMB 627 .word L(ipred_dc_h32) - L(ipred_dc_tbl) + CONFIG_THUMB 628 .word L(ipred_dc_h16) - L(ipred_dc_tbl) + CONFIG_THUMB 629 .word L(ipred_dc_h8) - L(ipred_dc_tbl) + CONFIG_THUMB 630 .word L(ipred_dc_h4) - L(ipred_dc_tbl) + CONFIG_THUMB 631 .word L(ipred_dc_w64) - L(ipred_dc_tbl) + CONFIG_THUMB 632 .word L(ipred_dc_w32) - L(ipred_dc_tbl) + CONFIG_THUMB 633 .word L(ipred_dc_w16) - L(ipred_dc_tbl) + CONFIG_THUMB 634 .word L(ipred_dc_w8) - L(ipred_dc_tbl) + CONFIG_THUMB 635 .word L(ipred_dc_w4) - L(ipred_dc_tbl) + CONFIG_THUMB 636 637L(ipred_dc_h4): 638 vld1.16 {d0}, [r2, :64]! 639 vpadd.i16 d0, d0, d0 640 add r2, r2, #2 641 vpaddl.u16 d0, d0 642 bx r3 643L(ipred_dc_w4): 644 vld1.16 {d2}, [r2] 645 vadd.i32 d0, d0, d30 646 vpadd.i16 d2, d2, d2 647 vpaddl.u16 d2, d2 648 cmp r4, #4 649 vadd.i32 d0, d0, d2 650 vshl.u32 d0, d0, d28 651 beq 1f 652 // h = 8/16 653 cmp r4, #16 654 movw lr, #0x6667 655 movw r5, #0xAAAB 656 it ne 657 movne lr, r5 658 vdup.32 d24, lr 659 vmul.i32 d0, d0, d24 660 vshr.u32 d0, d0, #17 6611: 662 vdup.16 d0, d0[0] 6632: 664 vst1.16 {d0}, [r0, :64], r1 665 vst1.16 {d0}, [r12, :64], r1 666 subs r4, r4, #4 667 vst1.16 {d0}, [r0, :64], r1 668 vst1.16 {d0}, [r12, :64], r1 669 bgt 2b 670 pop {r4-r6, pc} 671 672L(ipred_dc_h8): 673 vld1.16 {d0, d1}, [r2, :128]! 674 vadd.i16 d0, d0, d1 675 vpadd.i16 d0, d0, d0 676 add r2, r2, #2 677 vpaddl.u16 d0, d0 678 bx r3 679L(ipred_dc_w8): 680 vld1.16 {d2, d3}, [r2] 681 vadd.i32 d0, d0, d30 682 vadd.i16 d2, d2, d3 683 vpadd.i16 d2, d2, d2 684 vpaddl.u16 d2, d2 685 cmp r4, #8 686 vadd.i32 d0, d0, d2 687 vshl.u32 d0, d0, d28 688 beq 1f 689 // h = 4/16/32 690 cmp r4, #32 691 movw lr, #0x6667 692 movw r5, #0xAAAB 693 it ne 694 movne lr, r5 695 vdup.32 d24, lr 696 vmul.i32 d0, d0, d24 697 vshr.u32 d0, d0, #17 6981: 699 vdup.16 q0, d0[0] 7002: 701 vst1.16 {d0, d1}, [r0, :128], r1 702 vst1.16 {d0, d1}, [r12, :128], r1 703 subs r4, r4, #4 704 vst1.16 {d0, d1}, [r0, :128], r1 705 vst1.16 {d0, d1}, [r12, :128], r1 706 bgt 2b 707 pop {r4-r6, pc} 708 709L(ipred_dc_h16): 710 vld1.16 {d0, d1, d2, d3}, [r2, :128]! 711 vadd.i16 q0, q0, q1 712 vadd.i16 d0, d0, d1 713 vpadd.i16 d0, d0, d0 714 add r2, r2, #2 715 vpaddl.u16 d0, d0 716 bx r3 717L(ipred_dc_w16): 718 vld1.16 {d2, d3, d4, d5}, [r2] 719 vadd.i32 d0, d0, d30 720 vadd.i16 q1, q1, q2 721 vadd.i16 d2, d2, d3 722 vpadd.i16 d2, d2, d1 723 vpaddl.u16 d2, d2 724 cmp r4, #16 725 vadd.i32 d0, d0, d2 726 vshl.u32 d4, d0, d28 727 beq 1f 728 // h = 4/8/32/64 729 tst r4, #(32+16+8) // 16 added to make a consecutive bitmask 730 movw lr, #0x6667 731 movw r5, #0xAAAB 732 it ne 733 movne lr, r5 734 vdup.32 d24, lr 735 vmul.i32 d4, d4, d24 736 vshr.u32 d4, d4, #17 7371: 738 vdup.16 q0, d4[0] 739 vdup.16 q1, d4[0] 7402: 741 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 742 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 743 subs r4, r4, #4 744 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 745 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 746 bgt 2b 747 pop {r4-r6, pc} 748 749L(ipred_dc_h32): 750 vld1.16 {d0, d1, d2, d3}, [r2, :128]! 751 vld1.16 {d4, d5, d6, d7}, [r2, :128]! 752 vadd.i16 q0, q0, q1 753 vadd.i16 q2, q2, q3 754 vadd.i16 q0, q0, q2 755 vadd.i16 d0, d0, d1 756 vpadd.i16 d0, d0, d0 757 add r2, r2, #2 758 vpaddl.u16 d0, d0 759 bx r3 760L(ipred_dc_w32): 761 vld1.16 {d2, d3, d4, d5}, [r2]! 762 vadd.i32 d0, d0, d30 763 vld1.16 {d16, d17, d18, d19}, [r2] 764 vadd.i16 q1, q1, q2 765 vadd.i16 q8, q8, q9 766 vadd.i16 q1, q1, q8 767 vadd.i16 d2, d2, d3 768 vpadd.i16 d2, d2, d2 769 vpaddl.u16 d2, d2 770 cmp r4, #32 771 vadd.i32 d0, d0, d2 772 vshl.u32 d4, d0, d28 773 beq 1f 774 // h = 8/16/64 775 cmp r4, #8 776 movw lr, #0x6667 777 movw r5, #0xAAAB 778 it ne 779 movne lr, r5 780 vdup.32 d24, lr 781 vmul.i32 d4, d4, d24 782 vshr.u32 d4, d4, #17 7831: 784 sub r1, r1, #32 785 vdup.16 q0, d4[0] 786 vdup.16 q1, d4[0] 7872: 788 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 789 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 790 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 791 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 792 subs r4, r4, #4 793 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 794 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 795 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 796 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 797 bgt 2b 798 pop {r4-r6, pc} 799L(ipred_dc_h64): 800 vld1.16 {d0, d1, d2, d3}, [r2, :128]! 801 vld1.16 {d4, d5, d6, d7}, [r2, :128]! 802 vadd.i16 q0, q0, q1 803 vld1.16 {d16, d17, d18, d19}, [r2, :128]! 804 vadd.i16 q2, q2, q3 805 vld1.16 {d20, d21, d22, d23}, [r2, :128]! 806 vadd.i16 q8, q8, q9 807 vadd.i16 q10, q10, q11 808 vadd.i16 q0, q0, q2 809 vadd.i16 q8, q8, q10 810 vadd.i16 q0, q0, q8 811 vadd.i16 d0, d0, d1 812 vpaddl.u16 d0, d0 813 add r2, r2, #2 814 vpadd.i32 d0, d0, d0 815 bx r3 816L(ipred_dc_w64): 817 vld1.16 {d2, d3, d4, d5}, [r2]! 818 vadd.i32 d0, d0, d30 819 vld1.16 {d16, d17, d18, d19}, [r2]! 820 vadd.i16 q1, q1, q2 821 vld1.16 {d20, d21, d22, d23}, [r2]! 822 vadd.i16 q8, q8, q9 823 vld1.16 {d24, d25, d26, d27}, [r2]! 824 vadd.i16 q10, q10, q11 825 vadd.i16 q12, q12, q13 826 vadd.i16 q1, q1, q8 827 vadd.i16 q10, q10, q12 828 vadd.i16 q1, q1, q10 829 vadd.i16 d2, d2, d3 830 vpaddl.u16 d2, d2 831 vpadd.i32 d2, d2, d2 832 cmp r4, #64 833 vadd.i32 d0, d0, d2 834 vshl.u32 d4, d0, d28 835 beq 1f 836 // h = 16/32 837 cmp r4, #16 838 movw lr, #0x6667 839 movw r5, #0xAAAB 840 it ne 841 movne lr, r5 842 vdup.32 d24, lr 843 vmul.i32 d4, d4, d24 844 vshr.u32 d4, d4, #17 8451: 846 sub r1, r1, #96 847 vdup.16 q0, d4[0] 848 vdup.16 q1, d4[0] 8492: 850 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 851 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 852 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 853 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 854 subs r4, r4, #2 855 vst1.16 {d0, d1, d2, d3}, [r0, :128]! 856 vst1.16 {d0, d1, d2, d3}, [r12, :128]! 857 vst1.16 {d0, d1, d2, d3}, [r0, :128], r1 858 vst1.16 {d0, d1, d2, d3}, [r12, :128], r1 859 bgt 2b 860 pop {r4-r6, pc} 861endfunc 862 863// void ipred_paeth_16bpc_neon(pixel *dst, const ptrdiff_t stride, 864// const pixel *const topleft, 865// const int width, const int height, const int a, 866// const int max_width, const int max_height); 867function ipred_paeth_16bpc_neon, export=1 868 push {r4-r6, lr} 869 vpush {q4} 870 ldr r4, [sp, #32] 871 clz lr, r3 872 adr r12, L(ipred_paeth_tbl) 873 sub lr, lr, #25 874 ldr lr, [r12, lr, lsl #2] 875 vld1.16 {d4[], d5[]}, [r2] 876 add r6, r2, #2 877 sub r2, r2, #4 878 add r12, r12, lr 879 mov r5, #-4 880 add lr, r0, r1 881 lsl r1, r1, #1 882 bx r12 883 884 .align 2 885L(ipred_paeth_tbl): 886 .word 640f - L(ipred_paeth_tbl) + CONFIG_THUMB 887 .word 320f - L(ipred_paeth_tbl) + CONFIG_THUMB 888 .word 160f - L(ipred_paeth_tbl) + CONFIG_THUMB 889 .word 80f - L(ipred_paeth_tbl) + CONFIG_THUMB 890 .word 40f - L(ipred_paeth_tbl) + CONFIG_THUMB 891 89240: 893 sub r2, r2, #4 894 mov r5, #-8 895 vld1.16 {d6}, [r6] 896 vsub.i16 d16, d6, d4 // top - topleft 897 vmov d7, d6 898 vmov d17, d16 8994: 900 vld4.16 {d0[], d1[], d2[], d3[]}, [r2, :64], r5 901 vadd.i16 q9, q8, q0 // base 902 vadd.i16 q10, q8, q1 903 vabd.s16 q11, q3, q9 // tdiff 904 vabd.s16 q12, q3, q10 905 vabd.s16 q13, q2, q9 // tldiff 906 vabd.s16 q14, q2, q10 907 vabd.s16 q9, q0, q9 // ldiff 908 vabd.s16 q10, q1, q10 909 vmin.u16 q15, q11, q13 // min(tdiff, tldiff) 910 vmin.u16 q4, q12, q14 911 vcge.u16 q11, q13, q11 // tldiff >= tdiff 912 vcge.u16 q12, q14, q12 913 vcge.u16 q9, q15, q9 // min(tdiff, tldiff) >= ldiff 914 vcge.u16 q10, q4, q10 915 vbsl q12, q3, q2 // tdiff <= tldiff ? top : topleft 916 vbsl q11, q3, q2 917 vbit q12, q1, q10 // ldiff <= min ? left : ... 918 vbit q11, q0, q9 919 vst1.16 {d25}, [r0, :64], r1 920 vst1.16 {d24}, [lr, :64], r1 921 subs r4, r4, #4 922 vst1.16 {d23}, [r0, :64], r1 923 vst1.16 {d22}, [lr, :64], r1 924 bgt 4b 925 vpop {q4} 926 pop {r4-r6, pc} 92780: 928160: 929320: 930640: 931 vld1.16 {q3}, [r6]! 932 mov r12, r3 933 sub r1, r1, r3, lsl #1 9341: 935 vld2.16 {d0[], d2[]}, [r2, :32], r5 936 vmov d1, d0 937 vmov d3, d2 9382: 939 vsub.i16 q8, q3, q2 // top - topleft 940 vadd.i16 q9, q8, q0 // base 941 vadd.i16 q10, q8, q1 942 vabd.s16 q11, q3, q9 // tdiff 943 vabd.s16 q12, q3, q10 944 vabd.s16 q13, q2, q9 // tldiff 945 vabd.s16 q14, q2, q10 946 vabd.s16 q9, q0, q9 // ldiff 947 vabd.s16 q10, q1, q10 948 vmin.u16 q15, q11, q13 // min(tdiff, tldiff) 949 vmin.u16 q4, q12, q14 950 vcge.u16 q11, q13, q11 // tldiff >= tdiff 951 vcge.u16 q12, q14, q12 952 vcge.u16 q9, q15, q9 // min(tdiff, tldiff) >= ldiff 953 vcge.u16 q10, q4, q10 954 vbsl q12, q3, q2 // tdiff <= tldiff ? top : topleft 955 vbsl q11, q3, q2 956 vbit q12, q1, q10 // ldiff <= min ? left : ... 957 vbit q11, q0, q9 958 subs r3, r3, #8 959 vst1.16 {q12}, [r0, :128]! 960 vst1.16 {q11}, [lr, :128]! 961 ble 8f 962 vld1.16 {q3}, [r6]! 963 b 2b 9648: 965 subs r4, r4, #2 966 ble 9f 967 // End of horizontal loop, move pointers to next two rows 968 sub r6, r6, r12, lsl #1 969 add r0, r0, r1 970 add lr, lr, r1 971 vld1.16 {q3}, [r6]! 972 mov r3, r12 973 b 1b 9749: 975 vpop {q4} 976 pop {r4-r6, pc} 977endfunc 978 979// void ipred_smooth_16bpc_neon(pixel *dst, const ptrdiff_t stride, 980// const pixel *const topleft, 981// const int width, const int height, const int a, 982// const int max_width, const int max_height); 983function ipred_smooth_16bpc_neon, export=1 984 push {r4-r10, lr} 985 ldr r4, [sp, #32] 986 movrel r10, X(sm_weights) 987 add r12, r10, r4 988 add r10, r10, r3 989 clz r9, r3 990 adr r5, L(ipred_smooth_tbl) 991 sub lr, r2, r4, lsl #1 992 sub r9, r9, #25 993 ldr r9, [r5, r9, lsl #2] 994 vld1.16 {d4[], d5[]}, [lr] // bottom 995 add r8, r2, #2 996 add r5, r5, r9 997 add r6, r0, r1 998 lsl r1, r1, #1 999 bx r5 1000 1001 .align 2 1002L(ipred_smooth_tbl): 1003 .word 640f - L(ipred_smooth_tbl) + CONFIG_THUMB 1004 .word 320f - L(ipred_smooth_tbl) + CONFIG_THUMB 1005 .word 160f - L(ipred_smooth_tbl) + CONFIG_THUMB 1006 .word 80f - L(ipred_smooth_tbl) + CONFIG_THUMB 1007 .word 40f - L(ipred_smooth_tbl) + CONFIG_THUMB 1008 100940: 1010 vld1.16 {d16}, [r8] // top 1011 vld1.32 {d18[]}, [r10, :32] // weights_hor 1012 sub r2, r2, #8 1013 mov r7, #-8 1014 vdup.16 q3, d16[3] // right 1015 vsub.i16 q8, q8, q2 // top-bottom 1016 vmovl.u8 q9, d18 // weights_hor 1017 vadd.i16 d19, d4, d6 // bottom+right 10184: 1019 vld4.16 {d0[], d1[], d2[], d3[]}, [r2, :64], r7 // left 1020 vld4.8 {d20[], d21[], d22[], d23[]}, [r12, :32]! // weights_ver 1021 vshll.u16 q12, d19, #8 // (bottom+right)*256 1022 vshll.u16 q13, d19, #8 1023 vshll.u16 q14, d19, #8 1024 vshll.u16 q15, d19, #8 1025 vzip.32 d20, d21 // weights_ver 1026 vzip.32 d22, d23 1027 vsub.i16 q1, q1, q3 // left-right 1028 vsub.i16 q0, q0, q3 1029 vmovl.u8 q10, d20 // weights_ver 1030 vmovl.u8 q11, d22 1031 vmlal.s16 q12, d3, d18 // += (left-right)*weights_hor 1032 vmlal.s16 q13, d2, d18 // (left flipped) 1033 vmlal.s16 q14, d1, d18 1034 vmlal.s16 q15, d0, d18 1035 vmlal.s16 q12, d16, d20 // += (top-bottom)*weights_ver 1036 vmlal.s16 q13, d16, d21 1037 vmlal.s16 q14, d16, d22 1038 vmlal.s16 q15, d16, d23 1039 vrshrn.i32 d24, q12, #9 1040 vrshrn.i32 d25, q13, #9 1041 vrshrn.i32 d26, q14, #9 1042 vrshrn.i32 d27, q15, #9 1043 vst1.16 {d24}, [r0, :64], r1 1044 vst1.16 {d25}, [r6, :64], r1 1045 subs r4, r4, #4 1046 vst1.16 {d26}, [r0, :64], r1 1047 vst1.16 {d27}, [r6, :64], r1 1048 bgt 4b 1049 pop {r4-r10, pc} 105080: 1051 vld1.16 {q8}, [r8] // top 1052 vld1.8 {d18}, [r10, :64] // weights_hor 1053 sub r2, r2, #4 1054 mov r7, #-4 1055 vdup.16 q3, d17[3] // right 1056 vsub.i16 q8, q8, q2 // top-bottom 1057 vmovl.u8 q9, d18 // weights_hor 1058 vadd.i16 d3, d4, d6 // bottom+right 10598: 1060 vld2.16 {d0[], d1[]}, [r2, :32], r7 // left 1061 vld2.8 {d20[], d22[]}, [r12, :16]! // weights_ver 1062 vshll.u16 q12, d3, #8 // (bottom+right)*256 1063 vshll.u16 q13, d3, #8 1064 vshll.u16 q14, d3, #8 1065 vshll.u16 q15, d3, #8 1066 vsub.i16 q0, q0, q3 // left-right 1067 vmovl.u8 q10, d20 // weights_ver 1068 vmovl.u8 q11, d22 1069 vmlal.s16 q12, d1, d18 // += (left-right)*weights_hor 1070 vmlal.s16 q13, d1, d19 // (left flipped) 1071 vmlal.s16 q14, d0, d18 1072 vmlal.s16 q15, d0, d19 1073 vmlal.s16 q12, d16, d20 // += (top-bottom)*weights_ver 1074 vmlal.s16 q13, d17, d20 1075 vmlal.s16 q14, d16, d22 1076 vmlal.s16 q15, d17, d22 1077 vrshrn.i32 d24, q12, #9 1078 vrshrn.i32 d25, q13, #9 1079 vrshrn.i32 d26, q14, #9 1080 vrshrn.i32 d27, q15, #9 1081 subs r4, r4, #2 1082 vst1.16 {q12}, [r0, :128], r1 1083 vst1.16 {q13}, [r6, :128], r1 1084 bgt 8b 1085 pop {r4-r10, pc} 1086160: 1087320: 1088640: 1089 add lr, r2, r3, lsl #1 1090 sub r2, r2, #4 1091 mov r7, #-4 1092 vld1.16 {d6[], d7[]}, [lr] // right 1093 sub r1, r1, r3, lsl #1 1094 mov r9, r3 1095 vadd.i16 d3, d4, d6 // bottom+right 1096 10971: 1098 vld2.16 {d0[], d1[]}, [r2, :32], r7 // left 1099 vld2.8 {d20[], d22[]}, [r12, :16]! // weights_ver 1100 vsub.i16 q0, q0, q3 // left-right 1101 vmovl.u8 q10, d20 // weights_ver 1102 vmovl.u8 q11, d22 11032: 1104 vld1.8 {d18}, [r10, :64]! // weights_hor 1105 vld1.16 {q8}, [r8]! // top 1106 vshll.u16 q12, d3, #8 // (bottom+right)*256 1107 vshll.u16 q13, d3, #8 1108 vmovl.u8 q9, d18 // weights_hor 1109 vshll.u16 q14, d3, #8 1110 vshll.u16 q15, d3, #8 1111 vsub.i16 q8, q8, q2 // top-bottom 1112 vmlal.s16 q12, d1, d18 // += (left-right)*weights_hor 1113 vmlal.s16 q13, d1, d19 // (left flipped) 1114 vmlal.s16 q14, d0, d18 1115 vmlal.s16 q15, d0, d19 1116 vmlal.s16 q12, d16, d20 // += (top-bottom)*weights_ver 1117 vmlal.s16 q13, d17, d20 1118 vmlal.s16 q14, d16, d22 1119 vmlal.s16 q15, d17, d22 1120 vrshrn.i32 d24, q12, #9 1121 vrshrn.i32 d25, q13, #9 1122 vrshrn.i32 d26, q14, #9 1123 vrshrn.i32 d27, q15, #9 1124 subs r3, r3, #8 1125 vst1.16 {q12}, [r0, :128]! 1126 vst1.16 {q13}, [r6, :128]! 1127 bgt 2b 1128 subs r4, r4, #2 1129 ble 9f 1130 sub r8, r8, r9, lsl #1 1131 sub r10, r10, r9 1132 add r0, r0, r1 1133 add r6, r6, r1 1134 mov r3, r9 1135 b 1b 11369: 1137 pop {r4-r10, pc} 1138endfunc 1139 1140// void ipred_smooth_v_16bpc_neon(pixel *dst, const ptrdiff_t stride, 1141// const pixel *const topleft, 1142// const int width, const int height, const int a, 1143// const int max_width, const int max_height); 1144function ipred_smooth_v_16bpc_neon, export=1 1145 push {r4-r7, lr} 1146 ldr r4, [sp, #20] 1147 movrel r7, X(sm_weights) 1148 add r7, r7, r4 1149 clz lr, r3 1150 adr r5, L(ipred_smooth_v_tbl) 1151 sub r12, r2, r4, lsl #1 1152 sub lr, lr, #25 1153 ldr lr, [r5, lr, lsl #2] 1154 vld1.16 {d4[], d5[]}, [r12] // bottom 1155 add r2, r2, #2 1156 add r5, r5, lr 1157 add r6, r0, r1 1158 lsl r1, r1, #1 1159 bx r5 1160 1161 .align 2 1162L(ipred_smooth_v_tbl): 1163 .word 640f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1164 .word 320f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1165 .word 160f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1166 .word 80f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1167 .word 40f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1168 116940: 1170 vld1.16 {d6}, [r2] // top 1171 vsub.i16 d6, d6, d4 // top-bottom 1172 vmov d7, d6 11734: 1174 vld4.8 {d16[], d17[], d18[], d19[]}, [r7, :32]! // weights_ver 1175 vzip.32 d16, d17 // weights_ver 1176 vzip.32 d18, d19 1177 vshll.u8 q8, d16, #7 // weights_ver << 7 1178 vshll.u8 q9, d18, #7 1179 vqrdmulh.s16 q10, q3, q8 // ((top-bottom)*weights_ver + 128) >> 8 1180 vqrdmulh.s16 q11, q3, q9 1181 vadd.i16 q10, q10, q2 1182 vadd.i16 q11, q11, q2 1183 vst1.16 {d20}, [r0, :64], r1 1184 vst1.16 {d21}, [r6, :64], r1 1185 subs r4, r4, #4 1186 vst1.16 {d22}, [r0, :64], r1 1187 vst1.16 {d23}, [r6, :64], r1 1188 bgt 4b 1189 pop {r4-r7, pc} 119080: 1191 vld1.16 {q3}, [r2] // top 1192 vsub.i16 q3, q3, q2 // top-bottom 11938: 1194 vld4.8 {d16[], d18[], d20[], d22[]}, [r7, :32]! // weights_ver 1195 vshll.u8 q8, d16, #7 // weights_ver << 7 1196 vshll.u8 q9, d18, #7 1197 vshll.u8 q10, d20, #7 1198 vshll.u8 q11, d22, #7 1199 vqrdmulh.s16 q8, q3, q8 // ((top-bottom)*weights_ver + 128) >> 8 1200 vqrdmulh.s16 q9, q3, q9 1201 vqrdmulh.s16 q10, q3, q10 1202 vqrdmulh.s16 q11, q3, q11 1203 vadd.i16 q8, q8, q2 1204 vadd.i16 q9, q9, q2 1205 vadd.i16 q10, q10, q2 1206 vadd.i16 q11, q11, q2 1207 vst1.16 {q8}, [r0, :128], r1 1208 vst1.16 {q9}, [r6, :128], r1 1209 subs r4, r4, #4 1210 vst1.16 {q10}, [r0, :128], r1 1211 vst1.16 {q11}, [r6, :128], r1 1212 bgt 8b 1213 pop {r4-r7, pc} 1214160: 1215320: 1216640: 1217 vpush {q4-q7} 1218 // Set up pointers for four rows in parallel; r0, r6, r5, lr 1219 add r5, r0, r1 1220 add lr, r6, r1 1221 lsl r1, r1, #1 1222 sub r1, r1, r3, lsl #1 1223 mov r12, r3 1224 12251: 1226 vld4.8 {d8[], d10[], d12[], d14[]}, [r7, :32]! // weights_ver 1227 vshll.u8 q4, d8, #7 // weights_ver << 7 1228 vshll.u8 q5, d10, #7 1229 vshll.u8 q6, d12, #7 1230 vshll.u8 q7, d14, #7 12312: 1232 vld1.16 {q0, q1}, [r2]! // top 1233 vsub.i16 q0, q0, q2 // top-bottom 1234 vsub.i16 q1, q1, q2 1235 vqrdmulh.s16 q8, q0, q4 // ((top-bottom)*weights_ver + 128) >> 8 1236 vqrdmulh.s16 q9, q1, q4 1237 vqrdmulh.s16 q10, q0, q5 1238 vqrdmulh.s16 q11, q1, q5 1239 vqrdmulh.s16 q12, q0, q6 1240 vqrdmulh.s16 q13, q1, q6 1241 vqrdmulh.s16 q14, q0, q7 1242 vqrdmulh.s16 q15, q1, q7 1243 vadd.i16 q8, q8, q2 1244 vadd.i16 q9, q9, q2 1245 vadd.i16 q10, q10, q2 1246 vadd.i16 q11, q11, q2 1247 vadd.i16 q12, q12, q2 1248 vadd.i16 q13, q13, q2 1249 vadd.i16 q14, q14, q2 1250 vadd.i16 q15, q15, q2 1251 subs r3, r3, #16 1252 vst1.16 {q8, q9}, [r0, :128]! 1253 vst1.16 {q10, q11}, [r6, :128]! 1254 vst1.16 {q12, q13}, [r5, :128]! 1255 vst1.16 {q14, q15}, [lr, :128]! 1256 bgt 2b 1257 subs r4, r4, #4 1258 ble 9f 1259 sub r2, r2, r12, lsl #1 1260 add r0, r0, r1 1261 add r6, r6, r1 1262 add r5, r5, r1 1263 add lr, lr, r1 1264 mov r3, r12 1265 b 1b 12669: 1267 vpop {q4-q7} 1268 pop {r4-r7, pc} 1269endfunc 1270 1271// void ipred_smooth_h_16bpc_neon(pixel *dst, const ptrdiff_t stride, 1272// const pixel *const topleft, 1273// const int width, const int height, const int a, 1274// const int max_width, const int max_height); 1275function ipred_smooth_h_16bpc_neon, export=1 1276 push {r4-r8, lr} 1277 ldr r4, [sp, #24] 1278 movrel r8, X(sm_weights) 1279 add r8, r8, r3 1280 clz lr, r3 1281 adr r5, L(ipred_smooth_h_tbl) 1282 add r12, r2, r3, lsl #1 1283 sub lr, lr, #25 1284 ldr lr, [r5, lr, lsl #2] 1285 vld1.16 {d4[], d5[]}, [r12] // right 1286 add r5, r5, lr 1287 add r6, r0, r1 1288 lsl r1, r1, #1 1289 bx r5 1290 1291 .align 2 1292L(ipred_smooth_h_tbl): 1293 .word 640f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1294 .word 320f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1295 .word 160f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1296 .word 80f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1297 .word 40f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1298 129940: 1300 vld1.32 {d6[]}, [r8, :32] // weights_hor 1301 sub r2, r2, #8 1302 mov r7, #-8 1303 vshll.u8 q3, d6, #7 // weights_hor << 7 13044: 1305 vld4.16 {d0[], d1[], d2[], d3[]}, [r2, :64], r7 // left 1306 vsub.i16 q0, q0, q2 // left-right 1307 vsub.i16 q1, q1, q2 1308 subs r4, r4, #4 1309 vqrdmulh.s16 q8, q1, q3 // ((left-right)*weights_hor + 128) >> 8 1310 vqrdmulh.s16 q9, q0, q3 // (left flipped) 1311 vadd.i16 q8, q8, q2 1312 vadd.i16 q9, q9, q2 1313 vst1.16 {d17}, [r0, :64], r1 1314 vst1.16 {d16}, [r6, :64], r1 1315 vst1.16 {d19}, [r0, :64], r1 1316 vst1.16 {d18}, [r6, :64], r1 1317 bgt 4b 1318 pop {r4-r8, pc} 131980: 1320 vld1.8 {d6}, [r8, :64] // weights_hor 1321 sub r2, r2, #8 1322 mov r7, #-8 1323 vshll.u8 q3, d6, #7 // weights_hor << 7 13248: 1325 vld1.16 {d23}, [r2, :64], r7 // left 1326 subs r4, r4, #4 1327 vsub.i16 d23, d23, d4 // left-right 1328 vdup.16 q8, d23[3] // flip left 1329 vdup.16 q9, d23[2] 1330 vdup.16 q10, d23[1] 1331 vdup.16 q11, d23[0] 1332 vqrdmulh.s16 q8, q8, q3 // ((left-right)*weights_hor + 128) >> 8 1333 vqrdmulh.s16 q9, q9, q3 1334 vqrdmulh.s16 q10, q10, q3 1335 vqrdmulh.s16 q11, q11, q3 1336 vadd.i16 q8, q8, q2 1337 vadd.i16 q9, q9, q2 1338 vadd.i16 q10, q10, q2 1339 vadd.i16 q11, q11, q2 1340 vst1.16 {q8}, [r0, :128], r1 1341 vst1.16 {q9}, [r6, :128], r1 1342 vst1.16 {q10}, [r0, :128], r1 1343 vst1.16 {q11}, [r6, :128], r1 1344 bgt 8b 1345 pop {r4-r8, pc} 1346160: 1347320: 1348640: 1349 vpush {q4-q7} 1350 sub r2, r2, #8 1351 mov r7, #-8 1352 // Set up pointers for four rows in parallel; r0, r6, r5, lr 1353 add r5, r0, r1 1354 add lr, r6, r1 1355 lsl r1, r1, #1 1356 sub r1, r1, r3, lsl #1 1357 mov r12, r3 1358 13591: 1360 vld1.16 {d15}, [r2, :64], r7 // left 1361 vsub.i16 d15, d15, d4 // left-right 1362 vdup.16 q4, d15[3] // flip left 1363 vdup.16 q5, d15[2] 1364 vdup.16 q6, d15[1] 1365 vdup.16 q7, d15[0] 13662: 1367 vld1.8 {q1}, [r8, :128]! // weights_hor 1368 subs r3, r3, #16 1369 vshll.u8 q0, d2, #7 // weights_hor << 7 1370 vshll.u8 q1, d3, #7 1371 vqrdmulh.s16 q8, q0, q4 // ((left-right)*weights_hor + 128) >> 8 1372 vqrdmulh.s16 q9, q1, q4 1373 vqrdmulh.s16 q10, q0, q5 1374 vqrdmulh.s16 q11, q1, q5 1375 vqrdmulh.s16 q12, q0, q6 1376 vqrdmulh.s16 q13, q1, q6 1377 vqrdmulh.s16 q14, q0, q7 1378 vqrdmulh.s16 q15, q1, q7 1379 vadd.i16 q8, q8, q2 1380 vadd.i16 q9, q9, q2 1381 vadd.i16 q10, q10, q2 1382 vadd.i16 q11, q11, q2 1383 vadd.i16 q12, q12, q2 1384 vadd.i16 q13, q13, q2 1385 vadd.i16 q14, q14, q2 1386 vadd.i16 q15, q15, q2 1387 vst1.16 {q8, q9}, [r0, :128]! 1388 vst1.16 {q10, q11}, [r6, :128]! 1389 vst1.16 {q12, q13}, [r5, :128]! 1390 vst1.16 {q14, q15}, [lr, :128]! 1391 bgt 2b 1392 subs r4, r4, #4 1393 ble 9f 1394 sub r8, r8, r12 1395 add r0, r0, r1 1396 add r6, r6, r1 1397 add r5, r5, r1 1398 add lr, lr, r1 1399 mov r3, r12 1400 b 1b 14019: 1402 vpop {q4-q7} 1403 pop {r4-r8, pc} 1404endfunc 1405 1406// void ipred_filter_16bpc_neon(pixel *dst, const ptrdiff_t stride, 1407// const pixel *const topleft, 1408// const int width, const int height, const int filt_idx, 1409// const int max_width, const int max_height, 1410// const int bitdepth_max); 1411.macro filter_fn bpc 1412function ipred_filter_\bpc\()bpc_neon, export=1 1413 movw r12, #511 1414 ldrd r4, r5, [sp, #88] 1415 and r5, r5, r12 // 511 1416 movrel r6, X(filter_intra_taps) 1417 lsl r5, r5, #6 1418 add r6, r6, r5 1419 vld1.8 {d20, d21, d22, d23}, [r6, :128]! 1420 clz lr, r3 1421 adr r5, L(ipred_filter\bpc\()_tbl) 1422 vld1.8 {d27, d28, d29}, [r6, :64] 1423 sub lr, lr, #26 1424 ldr lr, [r5, lr, lsl #2] 1425 vmovl.s8 q8, d20 1426 vmovl.s8 q9, d21 1427 add r5, r5, lr 1428 vmovl.s8 q10, d22 1429 vmovl.s8 q11, d23 1430 add r6, r0, r1 1431 lsl r1, r1, #1 1432 vmovl.s8 q12, d27 1433 vmovl.s8 q13, d28 1434 vmovl.s8 q14, d29 1435 mov r7, #-4 1436 vdup.16 q15, r8 1437 add r8, r2, #2 1438 sub r2, r2, #4 1439.if \bpc == 10 1440 vmov.i16 q7, #0 1441.endif 1442 bx r5 1443 1444 .align 2 1445L(ipred_filter\bpc\()_tbl): 1446 .word 320f - L(ipred_filter\bpc\()_tbl) + CONFIG_THUMB 1447 .word 160f - L(ipred_filter\bpc\()_tbl) + CONFIG_THUMB 1448 .word 80f - L(ipred_filter\bpc\()_tbl) + CONFIG_THUMB 1449 .word 40f - L(ipred_filter\bpc\()_tbl) + CONFIG_THUMB 1450 145140: 1452 vld1.16 {d0}, [r8] // top (0-3) 14534: 1454 vld1.16 {d2}, [r2], r7 // left (0-1) + topleft (2) 1455.if \bpc == 10 1456 vmul.i16 q2, q9, d0[0] // p1(top[0]) * filter(1) 1457 vmla.i16 q2, q10, d0[1] // p2(top[1]) * filter(2) 1458 vmla.i16 q2, q11, d0[2] // p3(top[2]) * filter(3) 1459 vmla.i16 q2, q12, d0[3] // p4(top[3]) * filter(4) 1460 vmla.i16 q2, q8, d2[2] // p0(topleft) * filter(0) 1461 vmla.i16 q2, q13, d2[1] // p5(left[0]) * filter(5) 1462 vmla.i16 q2, q14, d2[0] // p6(left[1]) * filter(6) 1463 vrshr.s16 q2, q2, #4 1464 vmax.s16 q2, q2, q7 1465.else 1466 vmull.s16 q2, d18, d0[0] // p1(top[0]) * filter(1) 1467 vmlal.s16 q2, d20, d0[1] // p2(top[1]) * filter(2) 1468 vmlal.s16 q2, d22, d0[2] // p3(top[2]) * filter(3) 1469 vmlal.s16 q2, d24, d0[3] // p4(top[3]) * filter(4) 1470 vmlal.s16 q2, d16, d2[2] // p0(topleft) * filter(0) 1471 vmlal.s16 q2, d26, d2[1] // p5(left[0]) * filter(5) 1472 vmlal.s16 q2, d28, d2[0] // p6(left[1]) * filter(6) 1473 vmull.s16 q3, d19, d0[0] // p1(top[0]) * filter(1) 1474 vmlal.s16 q3, d21, d0[1] // p2(top[1]) * filter(2) 1475 vmlal.s16 q3, d23, d0[2] // p3(top[2]) * filter(3) 1476 vmlal.s16 q3, d25, d0[3] // p4(top[3]) * filter(4) 1477 vmlal.s16 q3, d17, d2[2] // p0(topleft) * filter(0) 1478 vmlal.s16 q3, d27, d2[1] // p5(left[0]) * filter(5) 1479 vmlal.s16 q3, d29, d2[0] // p6(left[1]) * filter(6) 1480 vqrshrun.s32 d4, q2, #4 1481 vqrshrun.s32 d5, q3, #4 1482.endif 1483 vmin.s16 q2, q2, q15 1484 subs r4, r4, #2 1485 vst1.16 {d4}, [r0, :64], r1 1486 vst1.16 {d5}, [r6, :64], r1 1487 vmov d0, d5 // move top from [4-7] to [0-3] 1488 bgt 4b 1489 vpop {q4-q7} 1490 pop {r4-r8, pc} 149180: 1492 vld1.16 {q0}, [r8] // top (0-7) 14938: 1494 vld1.16 {d2}, [r2], r7 // left (0-1) + topleft (2) 1495.if \bpc == 10 1496 vmul.i16 q2, q9, d0[0] // p1(top[0]) * filter(1) 1497 vmla.i16 q2, q10, d0[1] // p2(top[1]) * filter(2) 1498 vmla.i16 q2, q11, d0[2] // p3(top[2]) * filter(3) 1499 vmla.i16 q2, q12, d0[3] // p4(top[3]) * filter(4) 1500 vmla.i16 q2, q8, d2[2] // p0(topleft) * filter(0) 1501 vmla.i16 q2, q13, d2[1] // p5(left[0]) * filter(5) 1502 vmla.i16 q2, q14, d2[0] // p6(left[1]) * filter(6) 1503 vmul.i16 q3, q9, d1[0] // p1(top[0]) * filter(1) 1504 vmla.i16 q3, q10, d1[1] // p2(top[1]) * filter(2) 1505 vmla.i16 q3, q11, d1[2] // p3(top[2]) * filter(3) 1506 vrshr.s16 q2, q2, #4 1507 vmax.s16 q2, q2, q7 1508 vmin.s16 q2, q2, q15 1509 vmla.i16 q3, q12, d1[3] // p4(top[3]) * filter(4) 1510 vmla.i16 q3, q8, d0[3] // p0(topleft) * filter(0) 1511 vmla.i16 q3, q13, d4[3] // p5(left[0]) * filter(5) 1512 vmla.i16 q3, q14, d5[3] // p6(left[1]) * filter(6) 1513 vrshr.s16 q3, q3, #4 1514 vmax.s16 q3, q3, q7 1515.else 1516 vmull.s16 q2, d18, d0[0] // p1(top[0]) * filter(1) 1517 vmlal.s16 q2, d20, d0[1] // p2(top[1]) * filter(2) 1518 vmlal.s16 q2, d22, d0[2] // p3(top[2]) * filter(3) 1519 vmlal.s16 q2, d24, d0[3] // p4(top[3]) * filter(4) 1520 vmlal.s16 q2, d16, d2[2] // p0(topleft) * filter(0) 1521 vmlal.s16 q2, d26, d2[1] // p5(left[0]) * filter(5) 1522 vmlal.s16 q2, d28, d2[0] // p6(left[1]) * filter(6) 1523 vmull.s16 q3, d19, d0[0] // p1(top[0]) * filter(1) 1524 vmlal.s16 q3, d21, d0[1] // p2(top[1]) * filter(2) 1525 vmlal.s16 q3, d23, d0[2] // p3(top[2]) * filter(3) 1526 vmlal.s16 q3, d25, d0[3] // p4(top[3]) * filter(4) 1527 vmlal.s16 q3, d17, d2[2] // p0(topleft) * filter(0) 1528 vmlal.s16 q3, d27, d2[1] // p5(left[0]) * filter(5) 1529 vmlal.s16 q3, d29, d2[0] // p6(left[1]) * filter(6) 1530 vqrshrun.s32 d4, q2, #4 1531 vmull.s16 q4, d18, d1[0] // p1(top[0]) * filter(1) 1532 vmlal.s16 q4, d20, d1[1] // p2(top[1]) * filter(2) 1533 vmlal.s16 q4, d22, d1[2] // p3(top[2]) * filter(3) 1534 vqrshrun.s32 d5, q3, #4 1535 vmin.s16 q2, q2, q15 1536 vmlal.s16 q4, d24, d1[3] // p4(top[3]) * filter(4) 1537 vmlal.s16 q4, d16, d0[3] // p0(topleft) * filter(0) 1538 vmlal.s16 q4, d26, d4[3] // p5(left[0]) * filter(5) 1539 vmlal.s16 q4, d28, d5[3] // p6(left[1]) * filter(6) 1540 vmull.s16 q5, d19, d1[0] // p1(top[0]) * filter(1) 1541 vmlal.s16 q5, d21, d1[1] // p2(top[1]) * filter(2) 1542 vmlal.s16 q5, d23, d1[2] // p3(top[2]) * filter(3) 1543 vmlal.s16 q5, d25, d1[3] // p4(top[3]) * filter(4) 1544 vmlal.s16 q5, d17, d0[3] // p0(topleft) * filter(0) 1545 vmlal.s16 q5, d27, d4[3] // p5(left[0]) * filter(5) 1546 vmlal.s16 q5, d29, d5[3] // p6(left[1]) * filter(6) 1547 vqrshrun.s32 d6, q4, #4 1548 vqrshrun.s32 d7, q5, #4 1549.endif 1550 vmin.s16 q3, q3, q15 1551 vswp d5, d6 1552 subs r4, r4, #2 1553 vst1.16 {q2}, [r0, :128], r1 1554 vmov q0, q3 1555 vst1.16 {q3}, [r6, :128], r1 1556 bgt 8b 1557 vpop {q4-q7} 1558 pop {r4-r8, pc} 1559160: 1560320: 1561 sub r1, r1, r3, lsl #1 1562 mov lr, r3 1563 15641: 1565 vld1.16 {d0}, [r2], r7 // left (0-1) + topleft (2) 15662: 1567 vld1.16 {q1, q2}, [r8]! // top(0-15) 1568.if \bpc == 10 1569 vmul.i16 q3, q8, d0[2] // p0(topleft) * filter(0) 1570 vmla.i16 q3, q13, d0[1] // p5(left[0]) * filter(5) 1571 vmla.i16 q3, q14, d0[0] // p6(left[1]) * filter(6) 1572 vmla.i16 q3, q9, d2[0] // p1(top[0]) * filter(1) 1573 vmla.i16 q3, q10, d2[1] // p2(top[1]) * filter(2) 1574 vmla.i16 q3, q11, d2[2] // p3(top[2]) * filter(3) 1575 vmla.i16 q3, q12, d2[3] // p4(top[3]) * filter(4) 1576 1577 vmul.i16 q4, q9, d3[0] // p1(top[0]) * filter(1) 1578 vmla.i16 q4, q10, d3[1] // p2(top[1]) * filter(2) 1579 vmla.i16 q4, q11, d3[2] // p3(top[2]) * filter(3) 1580 vrshr.s16 q3, q3, #4 1581 vmax.s16 q3, q3, q7 1582 vmin.s16 q3, q3, q15 1583 vmla.i16 q4, q12, d3[3] // p4(top[3]) * filter(4) 1584 vmla.i16 q4, q8, d2[3] // p0(topleft) * filter(0) 1585 vmla.i16 q4, q13, d6[3] // p5(left[0]) * filter(5) 1586 vmla.i16 q4, q14, d7[3] // p6(left[1]) * filter(6) 1587 1588 vmul.i16 q5, q9, d4[0] // p1(top[0]) * filter(1) 1589 vmla.i16 q5, q10, d4[1] // p2(top[1]) * filter(2) 1590 vmla.i16 q5, q11, d4[2] // p3(top[2]) * filter(3) 1591 vrshr.s16 q4, q4, #4 1592 vmax.s16 q4, q4, q7 1593 vmin.s16 q4, q4, q15 1594 vmov q0, q4 1595 vmla.i16 q5, q12, d4[3] // p4(top[3]) * filter(4) 1596 vmla.i16 q5, q8, d3[3] // p0(topleft) * filter(0) 1597 vmla.i16 q5, q13, d0[3] // p5(left[0]) * filter(5) 1598 vmla.i16 q5, q14, d1[3] // p6(left[1]) * filter(6) 1599 1600 vmul.i16 q6, q9, d5[0] // p1(top[0]) * filter(1) 1601 vmla.i16 q6, q10, d5[1] // p2(top[1]) * filter(2) 1602 vmla.i16 q6, q11, d5[2] // p3(top[2]) * filter(3) 1603 vrshr.s16 q5, q5, #4 1604 vmax.s16 q5, q5, q7 1605 vmin.s16 q5, q5, q15 1606 vmov q0, q5 1607 vmov.u16 r12, d5[3] 1608 vmla.i16 q6, q12, d5[3] // p4(top[3]) * filter(4) 1609 vmla.i16 q6, q8, d4[3] // p0(topleft) * filter(0) 1610 vmla.i16 q6, q13, d0[3] // p5(left[0]) * filter(5) 1611 vmla.i16 q6, q14, d1[3] // p6(left[1]) * filter(6) 1612 vmov.16 d0[2], r12 1613 subs r3, r3, #16 1614 vrshr.s16 q6, q6, #4 1615.else 1616 vmull.s16 q3, d16, d0[2] // p0(topleft) * filter(0) 1617 vmlal.s16 q3, d26, d0[1] // p5(left[0]) * filter(5) 1618 vmlal.s16 q3, d28, d0[0] // p6(left[1]) * filter(6) 1619 vmlal.s16 q3, d18, d2[0] // p1(top[0]) * filter(1) 1620 vmlal.s16 q3, d20, d2[1] // p2(top[1]) * filter(2) 1621 vmlal.s16 q3, d22, d2[2] // p3(top[2]) * filter(3) 1622 vmlal.s16 q3, d24, d2[3] // p4(top[3]) * filter(4) 1623 vmull.s16 q4, d17, d0[2] // p0(topleft) * filter(0) 1624 vmlal.s16 q4, d27, d0[1] // p5(left[0]) * filter(5) 1625 vmlal.s16 q4, d29, d0[0] // p6(left[1]) * filter(6) 1626 vmlal.s16 q4, d19, d2[0] // p1(top[0]) * filter(1) 1627 vmlal.s16 q4, d21, d2[1] // p2(top[1]) * filter(2) 1628 vmlal.s16 q4, d23, d2[2] // p3(top[2]) * filter(3) 1629 vmlal.s16 q4, d25, d2[3] // p4(top[3]) * filter(4) 1630 vqrshrun.s32 d6, q3, #4 1631 vmull.s16 q5, d18, d3[0] // p1(top[0]) * filter(1) 1632 vmlal.s16 q5, d20, d3[1] // p2(top[1]) * filter(2) 1633 vqrshrun.s32 d7, q4, #4 1634 vmin.s16 q3, q3, q15 1635 vmlal.s16 q5, d22, d3[2] // p3(top[2]) * filter(3) 1636 vmlal.s16 q5, d24, d3[3] // p4(top[3]) * filter(4) 1637 vmlal.s16 q5, d16, d2[3] // p0(topleft) * filter(0) 1638 vmlal.s16 q5, d26, d6[3] // p5(left[0]) * filter(5) 1639 vmlal.s16 q5, d28, d7[3] // p6(left[1]) * filter(6) 1640 vmull.s16 q6, d19, d3[0] // p1(top[0]) * filter(1) 1641 vmlal.s16 q6, d21, d3[1] // p2(top[1]) * filter(2) 1642 vmlal.s16 q6, d23, d3[2] // p3(top[2]) * filter(3) 1643 vmlal.s16 q6, d25, d3[3] // p4(top[3]) * filter(4) 1644 vmlal.s16 q6, d17, d2[3] // p0(topleft) * filter(0) 1645 vmlal.s16 q6, d27, d6[3] // p5(left[0]) * filter(5) 1646 vmlal.s16 q6, d29, d7[3] // p6(left[1]) * filter(6) 1647 vqrshrun.s32 d8, q5, #4 1648 vmull.s16 q7, d18, d4[0] // p1(top[0]) * filter(1) 1649 vmlal.s16 q7, d20, d4[1] // p2(top[1]) * filter(2) 1650 vmlal.s16 q7, d22, d4[2] // p3(top[2]) * filter(3) 1651 vqrshrun.s32 d9, q6, #4 1652 vmin.s16 q0, q4, q15 1653 vmlal.s16 q7, d24, d4[3] // p4(top[3]) * filter(4) 1654 vmlal.s16 q7, d16, d3[3] // p0(topleft) * filter(0) 1655 vmlal.s16 q7, d26, d0[3] // p5(left[0]) * filter(5) 1656 vmlal.s16 q7, d28, d1[3] // p6(left[1]) * filter(6) 1657 vmin.s16 q4, q4, q15 1658 vmull.s16 q6, d19, d4[0] // p1(top[0]) * filter(1) 1659 vmlal.s16 q6, d21, d4[1] // p2(top[1]) * filter(2) 1660 vmlal.s16 q6, d23, d4[2] // p3(top[2]) * filter(3) 1661 vmlal.s16 q6, d25, d4[3] // p4(top[3]) * filter(4) 1662 vmlal.s16 q6, d17, d3[3] // p0(topleft) * filter(0) 1663 vmlal.s16 q6, d27, d0[3] // p5(left[0]) * filter(5) 1664 vmlal.s16 q6, d29, d1[3] // p6(left[1]) * filter(6) 1665 vqrshrun.s32 d10, q7, #4 1666 vmull.s16 q1, d18, d5[0] // p1(top[0]) * filter(1) 1667 vmlal.s16 q1, d20, d5[1] // p2(top[1]) * filter(2) 1668 vmlal.s16 q1, d22, d5[2] // p3(top[2]) * filter(3) 1669 vqrshrun.s32 d11, q6, #4 1670 vmin.s16 q0, q5, q15 1671 vmlal.s16 q1, d24, d5[3] // p4(top[3]) * filter(4) 1672 vmlal.s16 q1, d16, d4[3] // p0(topleft) * filter(0) 1673 vmlal.s16 q1, d26, d0[3] // p5(left[0]) * filter(5) 1674 vmlal.s16 q1, d28, d1[3] // p6(left[1]) * filter(6) 1675 vmin.s16 q5, q5, q15 1676 vmov.u16 r12, d5[3] 1677 vmull.s16 q7, d19, d5[0] // p1(top[0]) * filter(1) 1678 vmlal.s16 q7, d21, d5[1] // p2(top[1]) * filter(2) 1679 vmlal.s16 q7, d23, d5[2] // p3(top[2]) * filter(3) 1680 vmlal.s16 q7, d25, d5[3] // p4(top[3]) * filter(4) 1681 vmlal.s16 q7, d17, d4[3] // p0(topleft) * filter(0) 1682 vmlal.s16 q7, d27, d0[3] // p5(left[0]) * filter(5) 1683 vmlal.s16 q7, d29, d1[3] // p6(left[1]) * filter(6) 1684 vmov.16 d0[2], r12 1685 vqrshrun.s32 d12, q1, #4 1686 subs r3, r3, #16 1687 vqrshrun.s32 d13, q7, #4 1688.endif 1689 vswp q4, q5 1690.if \bpc == 10 1691 vmax.s16 q6, q6, q7 1692.endif 1693 vswp d7, d10 1694 vmin.s16 q6, q6, q15 1695 1696 vswp d9, d12 1697 1698 vst1.16 {q3, q4}, [r0, :128]! 1699 vst1.16 {q5, q6}, [r6, :128]! 1700 ble 8f 1701 vmov.u16 r12, d13[3] 1702 vmov.16 d0[0], r12 1703 vmov.u16 r12, d9[3] 1704 vmov.16 d0[1], r12 1705 b 2b 17068: 1707 subs r4, r4, #2 1708 1709 ble 9f 1710 sub r8, r6, lr, lsl #1 1711 add r0, r0, r1 1712 add r6, r6, r1 1713 mov r3, lr 1714 b 1b 17159: 1716 vpop {q4-q7} 1717 pop {r4-r8, pc} 1718endfunc 1719.endm 1720 1721filter_fn 10 1722filter_fn 12 1723 1724function ipred_filter_16bpc_neon, export=1 1725 push {r4-r8, lr} 1726 vpush {q4-q7} 1727 movw r12, 0x3ff 1728 ldr r8, [sp, #104] 1729 cmp r8, r12 1730 ble ipred_filter_10bpc_neon 1731 b ipred_filter_12bpc_neon 1732endfunc 1733 1734// void pal_pred_16bpc_neon(pixel *dst, const ptrdiff_t stride, 1735// const pixel *const pal, const uint8_t *idx, 1736// const int w, const int h); 1737function pal_pred_16bpc_neon, export=1 1738 push {r4-r5, lr} 1739 ldr r4, [sp, #12] 1740 ldr r5, [sp, #16] 1741 vld1.16 {q14}, [r2, :128] 1742 clz lr, r4 1743 adr r12, L(pal_pred_tbl) 1744 sub lr, lr, #25 1745 vmov.i8 q13, #7 1746 ldr lr, [r12, lr, lsl #2] 1747 vmov.i16 q15, #0x100 1748 add r12, r12, lr 1749 add r2, r0, r1 1750 bx r12 1751 1752 .align 2 1753L(pal_pred_tbl): 1754 .word 640f - L(pal_pred_tbl) + CONFIG_THUMB 1755 .word 320f - L(pal_pred_tbl) + CONFIG_THUMB 1756 .word 160f - L(pal_pred_tbl) + CONFIG_THUMB 1757 .word 80f - L(pal_pred_tbl) + CONFIG_THUMB 1758 .word 40f - L(pal_pred_tbl) + CONFIG_THUMB 1759 176040: 1761 lsl r1, r1, #1 17624: 1763 vld1.8 {d2}, [r3, :64]! 1764 subs r5, r5, #4 1765 vshr.u8 d3, d2, #4 1766 vand.u8 d2, d2, d26 1767 vzip.8 d2, d3 1768 // Restructure q1 from a, b, c, ... into 2*a, 2*a+1, 2*b, 2*b+1, 2*c, 2*c+1, ... 1769 vadd.i8 q0, q1, q1 1770 vadd.i8 q1, q1, q1 1771 vzip.8 q0, q1 1772 vadd.i16 q0, q0, q15 1773 vadd.i16 q1, q1, q15 1774 vtbl.8 d0, {q14}, d0 1775 vtbl.8 d1, {q14}, d1 1776 vst1.16 {d0}, [r0, :64], r1 1777 vtbl.8 d2, {q14}, d2 1778 vst1.16 {d1}, [r2, :64], r1 1779 vtbl.8 d3, {q14}, d3 1780 vst1.16 {d2}, [r0, :64], r1 1781 vst1.16 {d3}, [r2, :64], r1 1782 bgt 4b 1783 pop {r4-r5, pc} 178480: 1785 lsl r1, r1, #1 17868: 1787 vld1.8 {q1}, [r3, :64]! 1788 subs r5, r5, #4 1789 vshr.u8 q2, q1, #4 1790 vand.u8 q1, q1, q13 1791 vzip.8 q1, q2 1792 // Prefer doing the adds twice, instead of chaining a vmov after 1793 // the add. 1794 vadd.i8 q0, q1, q1 1795 vadd.i8 q1, q1, q1 1796 vadd.i8 q3, q2, q2 1797 vadd.i8 q2, q2, q2 1798 vzip.8 q0, q1 1799 vzip.8 q2, q3 1800 vadd.i16 q0, q0, q15 1801 vadd.i16 q1, q1, q15 1802 vtbl.8 d0, {q14}, d0 1803 vadd.i16 q2, q2, q15 1804 vtbl.8 d1, {q14}, d1 1805 vadd.i16 q3, q3, q15 1806 vtbl.8 d2, {q14}, d2 1807 vtbl.8 d3, {q14}, d3 1808 vtbl.8 d4, {q14}, d4 1809 vtbl.8 d5, {q14}, d5 1810 vst1.16 {q0}, [r0, :128], r1 1811 vtbl.8 d6, {q14}, d6 1812 vst1.16 {q1}, [r2, :128], r1 1813 vtbl.8 d7, {q14}, d7 1814 vst1.16 {q2}, [r0, :128], r1 1815 vst1.16 {q3}, [r2, :128], r1 1816 bgt 8b 1817 pop {r4-r5, pc} 1818160: 1819 lsl r1, r1, #1 182016: 1821 vld1.8 {q10, q11}, [r3, :64]! 1822 subs r5, r5, #4 1823 vand.u8 q2, q10, q13 1824 vshr.u8 q3, q10, #4 1825 vand.u8 q10, q11, q13 1826 vshr.u8 q11, q11, #4 1827 vzip.8 q2, q3 1828 vzip.8 q10, q11 1829 vadd.i8 q0, q2, q2 1830 vadd.i8 q1, q2, q2 1831 vadd.i8 q2, q3, q3 1832 vadd.i8 q3, q3, q3 1833 vadd.i8 q8, q10, q10 1834 vadd.i8 q9, q10, q10 1835 vadd.i8 q10, q11, q11 1836 vzip.8 q0, q1 1837 vadd.i8 q11, q11, q11 1838 vzip.8 q2, q3 1839 vzip.8 q8, q9 1840 vadd.i16 q0, q0, q15 1841 vzip.8 q10, q11 1842 vadd.i16 q1, q1, q15 1843 vadd.i16 q2, q2, q15 1844 vadd.i16 q3, q3, q15 1845 vadd.i16 q8, q8, q15 1846 vadd.i16 q9, q9, q15 1847 vadd.i16 q10, q10, q15 1848 vtbl.8 d0, {q14}, d0 1849 vadd.i16 q11, q11, q15 1850 vtbl.8 d1, {q14}, d1 1851 vtbl.8 d2, {q14}, d2 1852 vtbl.8 d3, {q14}, d3 1853 vtbl.8 d4, {q14}, d4 1854 vtbl.8 d5, {q14}, d5 1855 vtbl.8 d6, {q14}, d6 1856 vtbl.8 d7, {q14}, d7 1857 vtbl.8 d16, {q14}, d16 1858 vtbl.8 d17, {q14}, d17 1859 vtbl.8 d18, {q14}, d18 1860 vst1.16 {q0, q1}, [r0, :128], r1 1861 vtbl.8 d19, {q14}, d19 1862 vtbl.8 d20, {q14}, d20 1863 vst1.16 {q2, q3}, [r2, :128], r1 1864 vtbl.8 d21, {q14}, d21 1865 vtbl.8 d22, {q14}, d22 1866 vst1.16 {q8, q9}, [r0, :128], r1 1867 vtbl.8 d23, {q14}, d23 1868 vst1.16 {q10, q11}, [r2, :128], r1 1869 bgt 16b 1870 pop {r4-r5, pc} 1871320: 1872 lsl r1, r1, #1 1873 sub r1, r1, #32 187432: 1875 vld1.8 {q10, q11}, [r3, :64]! 1876 subs r5, r5, #2 1877 vand.u8 q2, q10, q13 1878 vshr.u8 q3, q10, #4 1879 vand.u8 q10, q11, q13 1880 vshr.u8 q11, q11, #4 1881 vzip.8 q2, q3 1882 vzip.8 q10, q11 1883 vadd.i8 q0, q2, q2 1884 vadd.i8 q1, q2, q2 1885 vadd.i8 q2, q3, q3 1886 vadd.i8 q3, q3, q3 1887 vadd.i8 q8, q10, q10 1888 vadd.i8 q9, q10, q10 1889 vadd.i8 q10, q11, q11 1890 vzip.8 q0, q1 1891 vadd.i8 q11, q11, q11 1892 vzip.8 q2, q3 1893 vzip.8 q8, q9 1894 vadd.i16 q0, q0, q15 1895 vzip.8 q10, q11 1896 vadd.i16 q1, q1, q15 1897 vadd.i16 q2, q2, q15 1898 vadd.i16 q3, q3, q15 1899 vadd.i16 q8, q8, q15 1900 vadd.i16 q9, q9, q15 1901 vadd.i16 q10, q10, q15 1902 vtbl.8 d0, {q14}, d0 1903 vadd.i16 q11, q11, q15 1904 vtbl.8 d1, {q14}, d1 1905 vtbl.8 d2, {q14}, d2 1906 vtbl.8 d3, {q14}, d3 1907 vtbl.8 d4, {q14}, d4 1908 vtbl.8 d5, {q14}, d5 1909 vtbl.8 d6, {q14}, d6 1910 vtbl.8 d7, {q14}, d7 1911 vtbl.8 d16, {q14}, d16 1912 vtbl.8 d17, {q14}, d17 1913 vtbl.8 d18, {q14}, d18 1914 vst1.16 {q0, q1}, [r0, :128]! 1915 vtbl.8 d19, {q14}, d19 1916 vtbl.8 d20, {q14}, d20 1917 vst1.16 {q2, q3}, [r0, :128], r1 1918 vtbl.8 d21, {q14}, d21 1919 vtbl.8 d22, {q14}, d22 1920 vst1.16 {q8, q9}, [r2, :128]! 1921 vtbl.8 d23, {q14}, d23 1922 vst1.16 {q10, q11}, [r2, :128], r1 1923 bgt 32b 1924 pop {r4-r5, pc} 1925640: 1926 sub r1, r1, #96 192764: 1928 vld1.8 {q10, q11}, [r3, :64]! 1929 subs r5, r5, #1 1930 vand.u8 q2, q10, q13 1931 vshr.u8 q3, q10, #4 1932 vand.u8 q10, q11, q13 1933 vshr.u8 q11, q11, #4 1934 vzip.8 q2, q3 1935 vzip.8 q10, q11 1936 vadd.i8 q0, q2, q2 1937 vadd.i8 q1, q2, q2 1938 vadd.i8 q2, q3, q3 1939 vadd.i8 q3, q3, q3 1940 vadd.i8 q8, q10, q10 1941 vadd.i8 q9, q10, q10 1942 vadd.i8 q10, q11, q11 1943 vzip.8 q0, q1 1944 vadd.i8 q11, q11, q11 1945 vzip.8 q2, q3 1946 vzip.8 q8, q9 1947 vadd.i16 q0, q0, q15 1948 vzip.8 q10, q11 1949 vadd.i16 q1, q1, q15 1950 vadd.i16 q2, q2, q15 1951 vadd.i16 q3, q3, q15 1952 vadd.i16 q8, q8, q15 1953 vadd.i16 q9, q9, q15 1954 vadd.i16 q10, q10, q15 1955 vtbl.8 d0, {q14}, d0 1956 vadd.i16 q11, q11, q15 1957 vtbl.8 d1, {q14}, d1 1958 vtbl.8 d2, {q14}, d2 1959 vtbl.8 d3, {q14}, d3 1960 vtbl.8 d4, {q14}, d4 1961 vtbl.8 d5, {q14}, d5 1962 vtbl.8 d6, {q14}, d6 1963 vtbl.8 d7, {q14}, d7 1964 vtbl.8 d16, {q14}, d16 1965 vtbl.8 d17, {q14}, d17 1966 vtbl.8 d18, {q14}, d18 1967 vst1.16 {q0, q1}, [r0, :128]! 1968 vtbl.8 d19, {q14}, d19 1969 vtbl.8 d20, {q14}, d20 1970 vst1.16 {q2, q3}, [r0, :128]! 1971 vtbl.8 d21, {q14}, d21 1972 vtbl.8 d22, {q14}, d22 1973 vst1.16 {q8, q9}, [r0, :128]! 1974 vtbl.8 d23, {q14}, d23 1975 vst1.16 {q10, q11}, [r0, :128], r1 1976 bgt 64b 1977 pop {r4-r5, pc} 1978endfunc 1979 1980// void ipred_cfl_128_16bpc_neon(pixel *dst, const ptrdiff_t stride, 1981// const pixel *const topleft, 1982// const int width, const int height, 1983// const int16_t *ac, const int alpha, 1984// const int bitdepth_max); 1985function ipred_cfl_128_16bpc_neon, export=1 1986 push {r4-r8, lr} 1987 ldrd r4, r5, [sp, #24] 1988 ldrd r6, r7, [sp, #32] 1989 clz lr, r3 1990 vdup.16 q15, r7 // bitdepth_max 1991 adr r12, L(ipred_cfl_128_tbl) 1992 sub lr, lr, #26 1993 ldr lr, [r12, lr, lsl #2] 1994 vrshr.u16 q0, q15, #1 1995 vdup.16 q1, r6 // alpha 1996 add r12, r12, lr 1997 add r6, r0, r1 1998 lsl r1, r1, #1 1999 vmov.i16 q14, #0 2000 bx r12 2001 2002 .align 2 2003L(ipred_cfl_128_tbl): 2004L(ipred_cfl_splat_tbl): 2005 .word L(ipred_cfl_splat_w16) - L(ipred_cfl_128_tbl) + CONFIG_THUMB 2006 .word L(ipred_cfl_splat_w16) - L(ipred_cfl_128_tbl) + CONFIG_THUMB 2007 .word L(ipred_cfl_splat_w8) - L(ipred_cfl_128_tbl) + CONFIG_THUMB 2008 .word L(ipred_cfl_splat_w4) - L(ipred_cfl_128_tbl) + CONFIG_THUMB 2009 2010L(ipred_cfl_splat_w4): 2011 vld1.16 {q8, q9}, [r5, :128]! 2012 vmull.s16 q2, d16, d2 // diff = ac * alpha 2013 vmull.s16 q3, d17, d3 2014 vmull.s16 q8, d18, d2 2015 vmull.s16 q9, d19, d3 2016 vshr.s32 q10, q2, #31 // sign = diff >> 15 2017 vshr.s32 q11, q3, #31 2018 vshr.s32 q12, q8, #31 2019 vshr.s32 q13, q9, #31 2020 vadd.i32 q2, q2, q10 // diff + sign 2021 vadd.i32 q3, q3, q11 2022 vadd.i32 q8, q8, q12 2023 vadd.i32 q9, q9, q13 2024 vrshrn.i32 d4, q2, #6 // (diff + sign + 32) >> 6 = apply_sign() 2025 vrshrn.i32 d5, q3, #6 2026 vrshrn.i32 d6, q8, #6 2027 vrshrn.i32 d7, q9, #6 2028 vadd.i16 q2, q2, q0 // dc + apply_sign() 2029 vadd.i16 q3, q3, q0 2030 vmax.s16 q2, q2, q14 2031 vmax.s16 q3, q3, q14 2032 vmin.s16 q2, q2, q15 2033 vmin.s16 q3, q3, q15 2034 vst1.16 {d4}, [r0, :64], r1 2035 vst1.16 {d5}, [r6, :64], r1 2036 subs r4, r4, #4 2037 vst1.16 {d6}, [r0, :64], r1 2038 vst1.16 {d7}, [r6, :64], r1 2039 bgt L(ipred_cfl_splat_w4) 2040 pop {r4-r8, pc} 2041L(ipred_cfl_splat_w8): 2042 vld1.16 {q8, q9}, [r5, :128]! 2043 subs r4, r4, #2 2044 vmull.s16 q2, d16, d2 // diff = ac * alpha 2045 vmull.s16 q3, d17, d3 2046 vmull.s16 q8, d18, d2 2047 vmull.s16 q9, d19, d3 2048 vshr.s32 q10, q2, #31 // sign = diff >> 15 2049 vshr.s32 q11, q3, #31 2050 vshr.s32 q12, q8, #31 2051 vshr.s32 q13, q9, #31 2052 vadd.i32 q2, q2, q10 // diff + sign 2053 vadd.i32 q3, q3, q11 2054 vadd.i32 q8, q8, q12 2055 vadd.i32 q9, q9, q13 2056 vrshrn.i32 d4, q2, #6 // (diff + sign + 32) >> 6 = apply_sign() 2057 vrshrn.i32 d5, q3, #6 2058 vrshrn.i32 d6, q8, #6 2059 vrshrn.i32 d7, q9, #6 2060 vadd.i16 q2, q2, q0 // dc + apply_sign() 2061 vadd.i16 q3, q3, q0 2062 vmax.s16 q2, q2, q14 2063 vmax.s16 q3, q3, q14 2064 vmin.s16 q2, q2, q15 2065 vmin.s16 q3, q3, q15 2066 vst1.16 {q2}, [r0, :128], r1 2067 vst1.16 {q3}, [r6, :128], r1 2068 bgt L(ipred_cfl_splat_w8) 2069 pop {r4-r8, pc} 2070L(ipred_cfl_splat_w16): 2071 vpush {q4-q7} 2072 add r12, r5, r3, lsl #1 2073 sub r1, r1, r3, lsl #1 2074 mov lr, r3 20751: 2076 vld1.16 {q6, q7}, [r5, :128]! 2077 vmull.s16 q2, d12, d2 // diff = ac * alpha 2078 vld1.16 {q8, q9}, [r12, :128]! 2079 vmull.s16 q3, d13, d3 2080 vmull.s16 q4, d14, d2 2081 vmull.s16 q5, d15, d3 2082 vmull.s16 q6, d16, d2 2083 vmull.s16 q7, d17, d3 2084 vmull.s16 q8, d18, d2 2085 vmull.s16 q9, d19, d3 2086 vshr.s32 q10, q2, #31 // sign = diff >> 15 2087 vshr.s32 q11, q3, #31 2088 vshr.s32 q12, q4, #31 2089 vshr.s32 q13, q5, #31 2090 vadd.i32 q2, q2, q10 // diff + sign 2091 vshr.s32 q10, q6, #31 2092 vadd.i32 q3, q3, q11 2093 vshr.s32 q11, q7, #31 2094 vadd.i32 q4, q4, q12 2095 vshr.s32 q12, q8, #31 2096 vadd.i32 q5, q5, q13 2097 vshr.s32 q13, q9, #31 2098 vadd.i32 q6, q6, q10 2099 vadd.i32 q7, q7, q11 2100 vadd.i32 q8, q8, q12 2101 vadd.i32 q9, q9, q13 2102 vrshrn.i32 d4, q2, #6 // (diff + sign + 32) >> 6 = apply_sign() 2103 vrshrn.i32 d5, q3, #6 2104 vrshrn.i32 d6, q4, #6 2105 vrshrn.i32 d7, q5, #6 2106 vadd.i16 q2, q2, q0 // dc + apply_sign() 2107 vrshrn.i32 d8, q6, #6 2108 vrshrn.i32 d9, q7, #6 2109 vadd.i16 q3, q3, q0 2110 vrshrn.i32 d10, q8, #6 2111 vrshrn.i32 d11, q9, #6 2112 vadd.i16 q4, q4, q0 2113 vadd.i16 q5, q5, q0 2114 vmax.s16 q2, q2, q14 2115 vmax.s16 q3, q3, q14 2116 vmax.s16 q4, q4, q14 2117 vmax.s16 q5, q5, q14 2118 vmin.s16 q2, q2, q15 2119 vmin.s16 q3, q3, q15 2120 vmin.s16 q4, q4, q15 2121 vmin.s16 q5, q5, q15 2122 subs r3, r3, #16 2123 vst1.16 {q2, q3}, [r0, :128]! 2124 vst1.16 {q4, q5}, [r6, :128]! 2125 bgt 1b 2126 subs r4, r4, #2 2127 add r5, r5, lr, lsl #1 2128 add r12, r12, lr, lsl #1 2129 add r0, r0, r1 2130 add r6, r6, r1 2131 mov r3, lr 2132 bgt 1b 2133 vpop {q4-q7} 2134 pop {r4-r8, pc} 2135endfunc 2136 2137// void ipred_cfl_top_16bpc_neon(pixel *dst, const ptrdiff_t stride, 2138// const pixel *const topleft, 2139// const int width, const int height, 2140// const int16_t *ac, const int alpha, 2141// const int bitdepth_max); 2142function ipred_cfl_top_16bpc_neon, export=1 2143 push {r4-r8, lr} 2144 ldrd r4, r5, [sp, #24] 2145 ldrd r6, r7, [sp, #32] 2146 clz lr, r3 2147 vdup.16 q15, r7 // bitdepth_max 2148 adr r12, L(ipred_cfl_top_tbl) 2149 sub lr, lr, #26 2150 ldr lr, [r12, lr, lsl #2] 2151 vdup.16 q1, r6 // alpha 2152 add r2, r2, #2 2153 add r12, r12, lr 2154 add r6, r0, r1 2155 lsl r1, r1, #1 2156 vmov.i16 q14, #0 2157 bx r12 2158 2159 .align 2 2160L(ipred_cfl_top_tbl): 2161 .word 32f - L(ipred_cfl_top_tbl) + CONFIG_THUMB 2162 .word 16f - L(ipred_cfl_top_tbl) + CONFIG_THUMB 2163 .word 8f - L(ipred_cfl_top_tbl) + CONFIG_THUMB 2164 .word 4f - L(ipred_cfl_top_tbl) + CONFIG_THUMB 2165 21664: 2167 vld1.16 {d0}, [r2] 2168 vpadd.i16 d0, d0, d0 2169 vpadd.i16 d0, d0, d0 2170 vrshr.u16 d0, d0, #2 2171 vdup.16 q0, d0[0] 2172 b L(ipred_cfl_splat_w4) 21738: 2174 vld1.16 {q0}, [r2] 2175 vadd.i16 d0, d0, d1 2176 vpadd.i16 d0, d0, d0 2177 vpadd.i16 d0, d0, d0 2178 vrshr.u16 d0, d0, #3 2179 vdup.16 q0, d0[0] 2180 b L(ipred_cfl_splat_w8) 218116: 2182 vld1.16 {q2, q3}, [r2] 2183 vadd.i16 q0, q2, q3 2184 vadd.i16 d0, d0, d1 2185 vpadd.i16 d0, d0, d0 2186 vpadd.i16 d0, d0, d0 2187 vrshr.u16 d0, d0, #4 2188 vdup.16 q0, d0[0] 2189 b L(ipred_cfl_splat_w16) 219032: 2191 vld1.16 {q8, q9}, [r2]! 2192 vld1.16 {q10, q11}, [r2] 2193 vadd.i16 q8, q8, q9 2194 vadd.i16 q10, q10, q11 2195 vadd.i16 q0, q8, q10 2196 vadd.i16 d0, d0, d1 2197 vpadd.i16 d0, d0, d0 2198 vpaddl.u16 d0, d0 2199 vrshrn.i32 d0, q0, #5 2200 vdup.16 q0, d0[0] 2201 b L(ipred_cfl_splat_w16) 2202endfunc 2203 2204// void ipred_cfl_left_16bpc_neon(pixel *dst, const ptrdiff_t stride, 2205// const pixel *const topleft, 2206// const int width, const int height, 2207// const int16_t *ac, const int alpha, 2208// const int bitdepth_max); 2209function ipred_cfl_left_16bpc_neon, export=1 2210 push {r4-r8, lr} 2211 ldrd r4, r5, [sp, #24] 2212 ldrd r6, r7, [sp, #32] 2213 sub r2, r2, r4, lsl #1 2214 clz lr, r3 2215 clz r8, r4 2216 vdup.16 q15, r7 // bitdepth_max 2217 adr r12, L(ipred_cfl_splat_tbl) 2218 adr r7, L(ipred_cfl_left_tbl) 2219 sub lr, lr, #26 2220 sub r8, r8, #26 2221 ldr lr, [r12, lr, lsl #2] 2222 ldr r8, [r7, r8, lsl #2] 2223 vdup.16 q1, r6 // alpha 2224 add r12, r12, lr 2225 add r7, r7, r8 2226 add r6, r0, r1 2227 lsl r1, r1, #1 2228 vmov.i16 q14, #0 2229 bx r7 2230 2231 .align 2 2232L(ipred_cfl_left_tbl): 2233 .word L(ipred_cfl_left_h32) - L(ipred_cfl_left_tbl) + CONFIG_THUMB 2234 .word L(ipred_cfl_left_h16) - L(ipred_cfl_left_tbl) + CONFIG_THUMB 2235 .word L(ipred_cfl_left_h8) - L(ipred_cfl_left_tbl) + CONFIG_THUMB 2236 .word L(ipred_cfl_left_h4) - L(ipred_cfl_left_tbl) + CONFIG_THUMB 2237 2238L(ipred_cfl_left_h4): 2239 vld1.16 {d0}, [r2, :64] 2240 vpadd.i16 d0, d0, d0 2241 vpadd.i16 d0, d0, d0 2242 vrshr.u16 d0, d0, #2 2243 vdup.16 q0, d0[0] 2244 bx r12 2245 2246L(ipred_cfl_left_h8): 2247 vld1.16 {q0}, [r2, :128] 2248 vadd.i16 d0, d0, d1 2249 vpadd.i16 d0, d0, d0 2250 vpadd.i16 d0, d0, d0 2251 vrshr.u16 d0, d0, #3 2252 vdup.16 q0, d0[0] 2253 bx r12 2254 2255L(ipred_cfl_left_h16): 2256 vld1.16 {q2, q3}, [r2, :128] 2257 vadd.i16 q0, q2, q3 2258 vadd.i16 d0, d0, d1 2259 vpadd.i16 d0, d0, d0 2260 vpadd.i16 d0, d0, d0 2261 vrshr.u16 d0, d0, #4 2262 vdup.16 q0, d0[0] 2263 bx r12 2264 2265L(ipred_cfl_left_h32): 2266 vld1.16 {q8, q9}, [r2, :128]! 2267 vld1.16 {q10, q11}, [r2, :128] 2268 vadd.i16 q8, q8, q9 2269 vadd.i16 q10, q10, q11 2270 vadd.i16 q0, q8, q10 2271 vadd.i16 d0, d0, d1 2272 vpadd.i16 d0, d0, d0 2273 vpaddl.u16 d0, d0 2274 vrshrn.i32 d0, q0, #5 2275 vdup.16 q0, d0[0] 2276 bx r12 2277endfunc 2278 2279// void ipred_cfl_16bpc_neon(pixel *dst, const ptrdiff_t stride, 2280// const pixel *const topleft, 2281// const int width, const int height, 2282// const int16_t *ac, const int alpha, 2283// const int bitdepth_max); 2284function ipred_cfl_16bpc_neon, export=1 2285 push {r4-r8, lr} 2286 ldrd r4, r5, [sp, #24] 2287 ldrd r6, r7, [sp, #32] 2288 sub r2, r2, r4, lsl #1 2289 add r8, r3, r4 // width + height 2290 vdup.16 q1, r6 // alpha 2291 clz lr, r3 2292 clz r6, r4 2293 vdup.32 d16, r8 // width + height 2294 vdup.16 q15, r7 // bitdepth_max 2295 adr r7, L(ipred_cfl_tbl) 2296 rbit r8, r8 // rbit(width + height) 2297 sub lr, lr, #22 // 26 leading bits, minus table offset 4 2298 sub r6, r6, #26 2299 clz r8, r8 // ctz(width + height) 2300 ldr lr, [r7, lr, lsl #2] 2301 ldr r6, [r7, r6, lsl #2] 2302 neg r8, r8 // -ctz(width + height) 2303 add r12, r7, lr 2304 add r7, r7, r6 2305 vshr.u32 d16, d16, #1 // (width + height) >> 1 2306 vdup.32 d17, r8 // -ctz(width + height) 2307 add r6, r0, r1 2308 lsl r1, r1, #1 2309 vmov.i16 q14, #0 2310 bx r7 2311 2312 .align 2 2313L(ipred_cfl_tbl): 2314 .word L(ipred_cfl_h32) - L(ipred_cfl_tbl) + CONFIG_THUMB 2315 .word L(ipred_cfl_h16) - L(ipred_cfl_tbl) + CONFIG_THUMB 2316 .word L(ipred_cfl_h8) - L(ipred_cfl_tbl) + CONFIG_THUMB 2317 .word L(ipred_cfl_h4) - L(ipred_cfl_tbl) + CONFIG_THUMB 2318 .word L(ipred_cfl_w32) - L(ipred_cfl_tbl) + CONFIG_THUMB 2319 .word L(ipred_cfl_w16) - L(ipred_cfl_tbl) + CONFIG_THUMB 2320 .word L(ipred_cfl_w8) - L(ipred_cfl_tbl) + CONFIG_THUMB 2321 .word L(ipred_cfl_w4) - L(ipred_cfl_tbl) + CONFIG_THUMB 2322 2323L(ipred_cfl_h4): 2324 vld1.16 {d0}, [r2, :64]! 2325 vpadd.i16 d0, d0, d0 2326 add r2, r2, #2 2327 vpaddl.u16 d0, d0 2328 bx r12 2329L(ipred_cfl_w4): 2330 vld1.16 {d1}, [r2] 2331 vadd.i32 d0, d0, d16 2332 vpadd.i16 d1, d1, d1 2333 vpaddl.u16 d1, d1 2334 cmp r4, #4 2335 vadd.i32 d0, d0, d1 2336 vshl.u32 d0, d0, d17 2337 beq 1f 2338 // h = 8/16 2339 cmp r4, #16 2340 movw lr, #0x6667 2341 movw r8, #0xAAAB 2342 it ne 2343 movne lr, r8 2344 vdup.32 d18, lr 2345 vmul.i32 d0, d0, d18 2346 vshr.u32 d0, d0, #17 23471: 2348 vdup.16 q0, d0[0] 2349 b L(ipred_cfl_splat_w4) 2350 2351L(ipred_cfl_h8): 2352 vld1.16 {q0}, [r2, :128]! 2353 vadd.i16 d0, d0, d1 2354 vpadd.i16 d0, d0, d0 2355 add r2, r2, #2 2356 vpaddl.u16 d0, d0 2357 bx r12 2358L(ipred_cfl_w8): 2359 vld1.16 {q2}, [r2] 2360 vadd.i32 d0, d0, d16 2361 vadd.i16 d1, d4, d5 2362 vpadd.i16 d1, d1, d1 2363 vpaddl.u16 d1, d1 2364 cmp r4, #8 2365 vadd.i32 d0, d0, d1 2366 vshl.u32 d0, d0, d17 2367 beq 1f 2368 // h = 4/16/32 2369 cmp r4, #32 2370 movw lr, #0x6667 2371 movw r8, #0xAAAB 2372 it ne 2373 movne lr, r8 2374 vdup.32 d18, lr 2375 vmul.i32 d0, d0, d18 2376 vshr.u32 d0, d0, #17 23771: 2378 vdup.16 q0, d0[0] 2379 b L(ipred_cfl_splat_w8) 2380 2381L(ipred_cfl_h16): 2382 vld1.16 {q2, q3}, [r2, :128]! 2383 vadd.i16 q0, q2, q3 2384 vadd.i16 d0, d0, d1 2385 vpadd.i16 d0, d0, d0 2386 add r2, r2, #2 2387 vpaddl.u16 d0, d0 2388 bx r12 2389L(ipred_cfl_w16): 2390 vld1.16 {q2, q3}, [r2] 2391 vadd.i32 d0, d0, d16 2392 vadd.i16 q2, q2, q3 2393 vadd.i16 d1, d4, d5 2394 vpadd.i16 d1, d1, d1 2395 vpaddl.u16 d1, d1 2396 cmp r4, #16 2397 vadd.i32 d0, d0, d1 2398 vshl.u32 d0, d0, d17 2399 beq 1f 2400 // h = 4/8/32/64 2401 tst r4, #(32+16+8) // 16 added to make a consecutive bitmask 2402 movw lr, #0x6667 2403 movw r8, #0xAAAB 2404 it ne 2405 movne lr, r8 2406 vdup.32 d18, lr 2407 vmul.i32 d0, d0, d18 2408 vshr.u32 d0, d0, #17 24091: 2410 vdup.16 q0, d0[0] 2411 b L(ipred_cfl_splat_w16) 2412 2413L(ipred_cfl_h32): 2414 vld1.16 {q2, q3}, [r2, :128]! 2415 vld1.16 {q10, q11}, [r2, :128]! 2416 vadd.i16 q2, q2, q3 2417 vadd.i16 q10, q10, q11 2418 vadd.i16 q0, q2, q10 2419 vadd.i16 d0, d0, d1 2420 vpadd.i16 d0, d0, d0 2421 add r2, r2, #2 2422 vpaddl.u16 d0, d0 2423 bx r12 2424L(ipred_cfl_w32): 2425 vld1.16 {q2, q3}, [r2]! 2426 vadd.i32 d0, d0, d16 2427 vld1.16 {q10, q11}, [r2]! 2428 vadd.i16 q2, q2, q3 2429 vadd.i16 q10, q10, q11 2430 vadd.i16 q2, q2, q10 2431 vadd.i16 d1, d4, d5 2432 vpadd.i16 d1, d1, d1 2433 vpaddl.u16 d1, d1 2434 cmp r4, #32 2435 vadd.i32 d0, d0, d1 2436 vshl.u32 d0, d0, d17 2437 beq 1f 2438 // h = 8/16/64 2439 cmp r4, #8 2440 movw lr, #0x6667 2441 movw r8, #0xAAAB 2442 it ne 2443 movne lr, r8 2444 vdup.32 d18, lr 2445 vmul.i32 d0, d0, d18 2446 vshr.u32 d0, d0, #17 24471: 2448 vdup.16 q0, d0[0] 2449 b L(ipred_cfl_splat_w16) 2450endfunc 2451 2452// void cfl_ac_420_16bpc_neon(int16_t *const ac, const pixel *const ypx, 2453// const ptrdiff_t stride, const int w_pad, 2454// const int h_pad, const int cw, const int ch); 2455function ipred_cfl_ac_420_16bpc_neon, export=1 2456 push {r4-r8,lr} 2457 ldrd r4, r5, [sp, #24] 2458 ldr r6, [sp, #32] 2459 clz r8, r5 2460 lsl r4, r4, #2 2461 adr r7, L(ipred_cfl_ac_420_tbl) 2462 sub r8, r8, #27 2463 ldr r8, [r7, r8, lsl #2] 2464 vmov.i32 q8, #0 2465 vmov.i32 q9, #0 2466 vmov.i32 q10, #0 2467 vmov.i32 q11, #0 2468 add r7, r7, r8 2469 sub r8, r6, r4 // height - h_pad 2470 rbit lr, r5 // rbit(width) 2471 rbit r12, r6 // rbit(height) 2472 clz lr, lr // ctz(width) 2473 clz r12, r12 // ctz(height) 2474 add lr, lr, r12 // log2sz 2475 add r12, r1, r2 2476 vdup.32 d31, lr 2477 lsl r2, r2, #1 2478 vneg.s32 d31, d31 // -log2sz 2479 bx r7 2480 2481 .align 2 2482L(ipred_cfl_ac_420_tbl): 2483 .word L(ipred_cfl_ac_420_w16) - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB 2484 .word L(ipred_cfl_ac_420_w8) - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB 2485 .word L(ipred_cfl_ac_420_w4) - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB 2486 2487L(ipred_cfl_ac_420_w4): 24881: // Copy and subsample input 2489 vld1.16 {q0}, [r1, :128], r2 2490 vld1.16 {q1}, [r12, :128], r2 2491 vld1.16 {q2}, [r1, :128], r2 2492 vld1.16 {q3}, [r12, :128], r2 2493 vadd.i16 q0, q0, q1 2494 vadd.i16 q2, q2, q3 2495 vpadd.i16 d0, d0, d1 2496 vpadd.i16 d1, d4, d5 2497 vshl.i16 q0, q0, #1 2498 subs r8, r8, #2 2499 vst1.16 {q0}, [r0, :128]! 2500 vaddw.u16 q8, q8, d0 2501 vaddw.u16 q9, q9, d1 2502 bgt 1b 2503 cmp r4, #0 2504 vmov d0, d1 2505 vmov d2, d1 2506 vmov d3, d1 2507L(ipred_cfl_ac_420_w4_hpad): 2508 beq 3f // This assumes that all callers already did "cmp r4, #0" 25092: // Vertical padding (h_pad > 0) 2510 subs r4, r4, #4 2511 vst1.16 {q0, q1}, [r0, :128]! 2512 vaddw.u16 q8, q8, d0 2513 vaddw.u16 q9, q9, d1 2514 vaddw.u16 q10, q10, d2 2515 vaddw.u16 q11, q11, d3 2516 bgt 2b 25173: 2518L(ipred_cfl_ac_420_w4_calc_subtract_dc): 2519 // Aggregate the sums 2520 vadd.i32 q8, q8, q9 2521 vadd.i32 q10, q10, q11 2522 vadd.i32 q0, q8, q10 2523 vadd.i32 d0, d0, d1 2524 vpadd.i32 d0, d0, d0 // sum 2525 sub r0, r0, r6, lsl #3 2526 vrshl.u32 d16, d0, d31 // (sum + (1 << (log2sz - 1))) >>= log2sz 2527 vdup.16 q8, d16[0] 25286: // Subtract dc from ac 2529 vld1.16 {q0, q1}, [r0, :128] 2530 subs r6, r6, #4 2531 vsub.i16 q0, q0, q8 2532 vsub.i16 q1, q1, q8 2533 vst1.16 {q0, q1}, [r0, :128]! 2534 bgt 6b 2535 pop {r4-r8, pc} 2536 2537L(ipred_cfl_ac_420_w8): 2538 cmp r3, #0 2539 bne L(ipred_cfl_ac_420_w8_wpad) 25401: // Copy and subsample input, without padding 2541 vld1.16 {q0, q1}, [r1, :128], r2 2542 vld1.16 {q2, q3}, [r12, :128], r2 2543 vld1.16 {q12, q13}, [r1, :128], r2 2544 vadd.i16 q0, q0, q2 2545 vadd.i16 q1, q1, q3 2546 vld1.16 {q2, q3}, [r12, :128], r2 2547 vpadd.i16 d0, d0, d1 2548 vpadd.i16 d1, d2, d3 2549 vadd.i16 q12, q12, q2 2550 vadd.i16 q13, q13, q3 2551 vpadd.i16 d2, d24, d25 2552 vpadd.i16 d3, d26, d27 2553 vshl.i16 q0, q0, #1 2554 vshl.i16 q1, q1, #1 2555 subs r8, r8, #2 2556 vst1.16 {q0, q1}, [r0, :128]! 2557 vaddw.u16 q8, q8, d0 2558 vaddw.u16 q9, q9, d1 2559 vaddw.u16 q10, q10, d2 2560 vaddw.u16 q11, q11, d3 2561 bgt 1b 2562 cmp r4, #0 2563 vmov q0, q1 2564 b L(ipred_cfl_ac_420_w8_hpad) 2565 2566L(ipred_cfl_ac_420_w8_wpad): 25671: // Copy and subsample input, padding 4 2568 vld1.16 {q0}, [r1, :128], r2 2569 vld1.16 {q1}, [r12, :128], r2 2570 vld1.16 {q2}, [r1, :128], r2 2571 vld1.16 {q3}, [r12, :128], r2 2572 vadd.i16 q0, q0, q1 2573 vadd.i16 q2, q2, q3 2574 vpadd.i16 d0, d0, d1 2575 vpadd.i16 d1, d4, d5 2576 vshl.i16 q0, q0, #1 2577 vdup.16 d3, d1[3] 2578 vmov d2, d1 2579 vdup.16 d1, d0[3] 2580 subs r8, r8, #2 2581 vst1.16 {q0, q1}, [r0, :128]! 2582 vaddw.u16 q8, q8, d0 2583 vaddw.u16 q9, q9, d1 2584 vaddw.u16 q10, q10, d2 2585 vaddw.u16 q11, q11, d3 2586 bgt 1b 2587 cmp r4, #0 2588 vmov q0, q1 2589 2590L(ipred_cfl_ac_420_w8_hpad): 2591 beq 3f // This assumes that all callers already did "cmp r4, #0" 25922: // Vertical padding (h_pad > 0) 2593 subs r4, r4, #4 2594 vst1.16 {q0, q1}, [r0, :128]! 2595 vaddw.u16 q8, q8, d0 2596 vaddw.u16 q9, q9, d1 2597 vaddw.u16 q10, q10, d2 2598 vaddw.u16 q11, q11, d3 2599 vst1.16 {q0, q1}, [r0, :128]! 2600 vaddw.u16 q8, q8, d0 2601 vaddw.u16 q9, q9, d1 2602 vaddw.u16 q10, q10, d2 2603 vaddw.u16 q11, q11, d3 2604 bgt 2b 26053: 2606 2607 // Double the height and reuse the w4 summing/subtracting 2608 lsl r6, r6, #1 2609 b L(ipred_cfl_ac_420_w4_calc_subtract_dc) 2610 2611L(ipred_cfl_ac_420_w16): 2612 adr r7, L(ipred_cfl_ac_420_w16_tbl) 2613 ldr r3, [r7, r3, lsl #2] 2614 add r7, r7, r3 2615 bx r7 2616 2617 .align 2 2618L(ipred_cfl_ac_420_w16_tbl): 2619 .word L(ipred_cfl_ac_420_w16_wpad0) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB 2620 .word L(ipred_cfl_ac_420_w16_wpad1) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB 2621 .word L(ipred_cfl_ac_420_w16_wpad2) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB 2622 .word L(ipred_cfl_ac_420_w16_wpad3) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB 2623 2624L(ipred_cfl_ac_420_w16_wpad0): 2625 sub r2, r2, #32 26261: // Copy and subsample input, without padding 2627 vld1.16 {q0, q1}, [r1, :128]! 2628 vld1.16 {q12, q13}, [r12, :128]! 2629 vld1.16 {q2, q3}, [r1, :128], r2 2630 vadd.i16 q0, q0, q12 2631 vadd.i16 q1, q1, q13 2632 vld1.16 {q12, q13}, [r12, :128], r2 2633 vpadd.i16 d0, d0, d1 2634 vpadd.i16 d1, d2, d3 2635 vadd.i16 q2, q2, q12 2636 vadd.i16 q3, q3, q13 2637 vpadd.i16 d2, d4, d5 2638 vpadd.i16 d3, d6, d7 2639 vshl.i16 q0, q0, #1 2640 vshl.i16 q1, q1, #1 2641 subs r8, r8, #1 2642 vst1.16 {q0, q1}, [r0, :128]! 2643 vaddw.u16 q8, q8, d0 2644 vaddw.u16 q9, q9, d1 2645 vaddw.u16 q10, q10, d2 2646 vaddw.u16 q11, q11, d3 2647 bgt 1b 2648 cmp r4, #0 2649 b L(ipred_cfl_ac_420_w16_hpad) 2650 2651L(ipred_cfl_ac_420_w16_wpad1): 2652 sub r2, r2, #32 26531: // Copy and subsample input, padding 4 2654 vld1.16 {q0, q1}, [r1, :128]! 2655 vld1.16 {q12, q13}, [r12, :128]! 2656 vld1.16 {q2}, [r1, :128], r2 2657 vadd.i16 q0, q0, q12 2658 vadd.i16 q1, q1, q13 2659 vld1.16 {q12}, [r12, :128], r2 2660 vpadd.i16 d0, d0, d1 2661 vadd.i16 q2, q2, q12 2662 vpadd.i16 d1, d2, d3 2663 vpadd.i16 d2, d4, d5 2664 vshl.i16 q0, q0, #1 2665 vshl.i16 d2, d2, #1 2666 subs r8, r8, #1 2667 vdup.16 d3, d2[3] 2668 vst1.16 {q0, q1}, [r0, :128]! 2669 vaddw.u16 q8, q8, d0 2670 vaddw.u16 q9, q9, d1 2671 vaddw.u16 q10, q10, d2 2672 vaddw.u16 q11, q11, d3 2673 bgt 1b 2674 cmp r4, #0 2675 b L(ipred_cfl_ac_420_w16_hpad) 2676 2677L(ipred_cfl_ac_420_w16_wpad2): 26781: // Copy and subsample input, padding 8 2679 vld1.16 {q0, q1}, [r1, :128], r2 2680 vld1.16 {q12, q13}, [r12, :128], r2 2681 vadd.i16 q0, q0, q12 2682 vadd.i16 q1, q1, q13 2683 vpadd.i16 d0, d0, d1 2684 vpadd.i16 d1, d2, d3 2685 vshl.i16 q0, q0, #1 2686 subs r8, r8, #1 2687 vdup.16 q1, d1[3] 2688 vst1.16 {q0, q1}, [r0, :128]! 2689 vaddw.u16 q8, q8, d0 2690 vaddw.u16 q9, q9, d1 2691 vaddw.u16 q10, q10, d2 2692 vaddw.u16 q11, q11, d3 2693 bgt 1b 2694 cmp r4, #0 2695 b L(ipred_cfl_ac_420_w16_hpad) 2696 2697L(ipred_cfl_ac_420_w16_wpad3): 26981: // Copy and subsample input, padding 12 2699 vld1.16 {q0}, [r1, :128], r2 2700 vld1.16 {q12}, [r12, :128], r2 2701 vadd.i16 q0, q0, q12 2702 vpadd.i16 d0, d0, d1 2703 vshl.i16 d0, d0, #1 2704 subs r8, r8, #1 2705 vdup.16 q1, d0[3] 2706 vdup.16 d1, d0[3] 2707 vst1.16 {q0, q1}, [r0, :128]! 2708 vaddw.u16 q8, q8, d0 2709 vaddw.u16 q9, q9, d1 2710 vaddw.u16 q10, q10, d2 2711 vaddw.u16 q11, q11, d3 2712 bgt 1b 2713 cmp r4, #0 2714 b L(ipred_cfl_ac_420_w16_hpad) 2715 2716L(ipred_cfl_ac_420_w16_hpad): 2717 beq 3f // This assumes that all callers already did "cmp r4, #0" 27182: // Vertical padding (h_pad > 0) 2719 subs r4, r4, #2 2720 vst1.16 {q0, q1}, [r0, :128]! 2721 vaddw.u16 q8, q8, d0 2722 vaddw.u16 q9, q9, d1 2723 vaddw.u16 q10, q10, d2 2724 vaddw.u16 q11, q11, d3 2725 vst1.16 {q0, q1}, [r0, :128]! 2726 vaddw.u16 q8, q8, d0 2727 vaddw.u16 q9, q9, d1 2728 vaddw.u16 q10, q10, d2 2729 vaddw.u16 q11, q11, d3 2730 bgt 2b 27313: 2732 2733 // Quadruple the height and reuse the w4 summing/subtracting 2734 lsl r6, r6, #2 2735 b L(ipred_cfl_ac_420_w4_calc_subtract_dc) 2736endfunc 2737 2738// void cfl_ac_422_16bpc_neon(int16_t *const ac, const pixel *const ypx, 2739// const ptrdiff_t stride, const int w_pad, 2740// const int h_pad, const int cw, const int ch); 2741function ipred_cfl_ac_422_16bpc_neon, export=1 2742 push {r4-r8,lr} 2743 ldrd r4, r5, [sp, #24] 2744 ldr r6, [sp, #32] 2745 clz r8, r5 2746 lsl r4, r4, #2 2747 adr r7, L(ipred_cfl_ac_422_tbl) 2748 sub r8, r8, #27 2749 ldr r8, [r7, r8, lsl #2] 2750 vmov.i16 q8, #0 2751 vmov.i16 q9, #0 2752 vmov.i16 q10, #0 2753 vmov.i16 q11, #0 2754 add r7, r7, r8 2755 sub r8, r6, r4 // height - h_pad 2756 rbit lr, r5 // rbit(width) 2757 rbit r12, r6 // rbit(height) 2758 clz lr, lr // ctz(width) 2759 clz r12, r12 // ctz(height) 2760 add lr, lr, r12 // log2sz 2761 add r12, r1, r2 2762 vdup.32 d31, lr 2763 lsl r2, r2, #1 2764 vneg.s32 d31, d31 // -log2sz 2765 bx r7 2766 2767 .align 2 2768L(ipred_cfl_ac_422_tbl): 2769 .word L(ipred_cfl_ac_422_w16) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB 2770 .word L(ipred_cfl_ac_422_w8) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB 2771 .word L(ipred_cfl_ac_422_w4) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB 2772 2773L(ipred_cfl_ac_422_w4): 27741: // Copy and subsample input 2775 vld1.16 {q0}, [r1, :128], r2 2776 vld1.16 {q1}, [r12, :128], r2 2777 vld1.16 {q2}, [r1, :128], r2 2778 vld1.16 {q3}, [r12, :128], r2 2779 vpadd.i16 d0, d0, d1 2780 vpadd.i16 d1, d2, d3 2781 vpadd.i16 d2, d4, d5 2782 vpadd.i16 d3, d6, d7 2783 vshl.i16 q0, q0, #2 2784 vshl.i16 q1, q1, #2 2785 subs r8, r8, #4 2786 vst1.16 {q0, q1}, [r0, :128]! 2787 vaddw.u16 q8, q8, d0 2788 vaddw.u16 q9, q9, d1 2789 vaddw.u16 q10, q10, d2 2790 vaddw.u16 q11, q11, d3 2791 bgt 1b 2792 cmp r4, #0 2793 vmov d0, d3 2794 vmov d1, d3 2795 vmov d2, d3 2796 b L(ipred_cfl_ac_420_w4_hpad) 2797 2798L(ipred_cfl_ac_422_w8): 2799 cmp r3, #0 2800 bne L(ipred_cfl_ac_422_w8_wpad) 28011: // Copy and subsample input, without padding 2802 vld1.16 {q0, q1}, [r1, :128], r2 2803 vld1.16 {q2, q3}, [r12, :128], r2 2804 vld1.16 {q12, q13}, [r1, :128], r2 2805 vpadd.i16 d0, d0, d1 2806 vpadd.i16 d1, d2, d3 2807 vpadd.i16 d2, d4, d5 2808 vpadd.i16 d3, d6, d7 2809 vld1.16 {q2, q3}, [r12, :128], r2 2810 vpadd.i16 d24, d24, d25 2811 vpadd.i16 d25, d26, d27 2812 vpadd.i16 d26, d4, d5 2813 vpadd.i16 d27, d6, d7 2814 vshl.i16 q0, q0, #2 2815 vshl.i16 q1, q1, #2 2816 vshl.i16 q2, q12, #2 2817 vshl.i16 q3, q13, #2 2818 subs r8, r8, #4 2819 vst1.16 {q0, q1}, [r0, :128]! 2820 vaddw.u16 q8, q8, d0 2821 vaddw.u16 q9, q9, d1 2822 vaddw.u16 q10, q10, d2 2823 vaddw.u16 q11, q11, d3 2824 vst1.16 {q2, q3}, [r0, :128]! 2825 vaddw.u16 q8, q8, d4 2826 vaddw.u16 q9, q9, d5 2827 vaddw.u16 q10, q10, d6 2828 vaddw.u16 q11, q11, d7 2829 bgt 1b 2830 cmp r4, #0 2831 vmov q0, q3 2832 vmov q1, q3 2833 b L(ipred_cfl_ac_420_w8_hpad) 2834 2835L(ipred_cfl_ac_422_w8_wpad): 28361: // Copy and subsample input, padding 4 2837 vld1.16 {q0}, [r1, :128], r2 2838 vld1.16 {q2}, [r12, :128], r2 2839 vld1.16 {q12}, [r1, :128], r2 2840 vpadd.i16 d0, d0, d1 2841 vpadd.i16 d1, d4, d5 2842 vld1.16 {q2, q3}, [r12, :128], r2 2843 vpadd.i16 d24, d24, d25 2844 vpadd.i16 d25, d4, d5 2845 vshl.i16 q0, q0, #2 2846 vshl.i16 q12, q12, #2 2847 vdup.16 d7, d25[3] 2848 vmov d6, d25 2849 vdup.16 d5, d24[3] 2850 vmov d4, d24 2851 vdup.16 d3, d1[3] 2852 vmov d2, d1 2853 vdup.16 d1, d0[3] 2854 subs r8, r8, #4 2855 vst1.16 {q0, q1}, [r0, :128]! 2856 vaddw.u16 q8, q8, d0 2857 vaddw.u16 q9, q9, d1 2858 vaddw.u16 q10, q10, d2 2859 vaddw.u16 q11, q11, d3 2860 vst1.16 {q2, q3}, [r0, :128]! 2861 vaddw.u16 q8, q8, d4 2862 vaddw.u16 q9, q9, d5 2863 vaddw.u16 q10, q10, d6 2864 vaddw.u16 q11, q11, d7 2865 bgt 1b 2866 cmp r4, #0 2867 vmov q0, q3 2868 vmov q1, q3 2869 b L(ipred_cfl_ac_420_w8_hpad) 2870 2871L(ipred_cfl_ac_422_w16): 2872 adr r7, L(ipred_cfl_ac_422_w16_tbl) 2873 ldr r3, [r7, r3, lsl #2] 2874 add r7, r7, r3 2875 bx r7 2876 2877 .align 2 2878L(ipred_cfl_ac_422_w16_tbl): 2879 .word L(ipred_cfl_ac_422_w16_wpad0) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB 2880 .word L(ipred_cfl_ac_422_w16_wpad1) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB 2881 .word L(ipred_cfl_ac_422_w16_wpad2) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB 2882 .word L(ipred_cfl_ac_422_w16_wpad3) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB 2883 2884L(ipred_cfl_ac_422_w16_wpad0): 2885 sub r2, r2, #32 28861: // Copy and subsample input, without padding 2887 vld1.16 {q0, q1}, [r1, :128]! 2888 vld1.16 {q2, q3}, [r12, :128]! 2889 vld1.16 {q12, q13}, [r1, :128], r2 2890 vpadd.i16 d0, d0, d1 2891 vpadd.i16 d1, d2, d3 2892 vpadd.i16 d2, d24, d25 2893 vpadd.i16 d3, d26, d27 2894 vld1.16 {q12, q13}, [r12, :128], r2 2895 vpadd.i16 d4, d4, d5 2896 vpadd.i16 d5, d6, d7 2897 vpadd.i16 d6, d24, d25 2898 vpadd.i16 d7, d26, d27 2899 vshl.i16 q0, q0, #2 2900 vshl.i16 q1, q1, #2 2901 vshl.i16 q2, q2, #2 2902 vshl.i16 q3, q3, #2 2903 subs r8, r8, #2 2904 vst1.16 {q0, q1}, [r0, :128]! 2905 vaddw.u16 q8, q8, d0 2906 vaddw.u16 q9, q9, d1 2907 vaddw.u16 q10, q10, d2 2908 vaddw.u16 q11, q11, d3 2909 vst1.16 {q2, q3}, [r0, :128]! 2910 vaddw.u16 q8, q8, d4 2911 vaddw.u16 q9, q9, d5 2912 vaddw.u16 q10, q10, d6 2913 vaddw.u16 q11, q11, d7 2914 bgt 1b 2915 cmp r4, #0 2916 vmov q0, q2 2917 vmov q1, q3 2918 b L(ipred_cfl_ac_420_w16_hpad) 2919 2920L(ipred_cfl_ac_422_w16_wpad1): 2921 sub r2, r2, #32 29221: // Copy and subsample input, padding 4 2923 vld1.16 {q0, q1}, [r1, :128]! 2924 vld1.16 {q2, q3}, [r12, :128]! 2925 vld1.16 {q12}, [r1, :128], r2 2926 vpadd.i16 d0, d0, d1 2927 vpadd.i16 d1, d2, d3 2928 vpadd.i16 d2, d24, d25 2929 vld1.16 {q12}, [r12, :128], r2 2930 vpadd.i16 d4, d4, d5 2931 vpadd.i16 d5, d6, d7 2932 vpadd.i16 d6, d24, d25 2933 vshl.i16 q0, q0, #2 2934 vshl.i16 d2, d2, #2 2935 vshl.i16 q2, q2, #2 2936 vshl.i16 d6, d6, #2 2937 vdup.16 d3, d2[3] 2938 vdup.16 d7, d6[3] 2939 subs r8, r8, #2 2940 vst1.16 {q0, q1}, [r0, :128]! 2941 vaddw.u16 q8, q8, d0 2942 vaddw.u16 q9, q9, d1 2943 vaddw.u16 q10, q10, d2 2944 vaddw.u16 q11, q11, d3 2945 vst1.16 {q2, q3}, [r0, :128]! 2946 vaddw.u16 q8, q8, d4 2947 vaddw.u16 q9, q9, d5 2948 vaddw.u16 q10, q10, d6 2949 vaddw.u16 q11, q11, d7 2950 bgt 1b 2951 cmp r4, #0 2952 vmov q0, q2 2953 vmov q1, q3 2954 b L(ipred_cfl_ac_420_w16_hpad) 2955 2956L(ipred_cfl_ac_422_w16_wpad2): 29571: // Copy and subsample input, padding 8 2958 vld1.16 {q0, q1}, [r1, :128], r2 2959 vld1.16 {q2, q3}, [r12, :128], r2 2960 vpadd.i16 d0, d0, d1 2961 vpadd.i16 d1, d2, d3 2962 vpadd.i16 d4, d4, d5 2963 vpadd.i16 d5, d6, d7 2964 vshl.i16 q0, q0, #2 2965 vshl.i16 q2, q2, #2 2966 vdup.16 q1, d1[3] 2967 vdup.16 q3, d5[3] 2968 subs r8, r8, #2 2969 vst1.16 {q0, q1}, [r0, :128]! 2970 vaddw.u16 q8, q8, d0 2971 vaddw.u16 q9, q9, d1 2972 vaddw.u16 q10, q10, d2 2973 vaddw.u16 q11, q11, d3 2974 vst1.16 {q2, q3}, [r0, :128]! 2975 vaddw.u16 q8, q8, d4 2976 vaddw.u16 q9, q9, d5 2977 vaddw.u16 q10, q10, d6 2978 vaddw.u16 q11, q11, d7 2979 bgt 1b 2980 cmp r4, #0 2981 vmov q0, q2 2982 vmov q1, q3 2983 b L(ipred_cfl_ac_420_w16_hpad) 2984 2985L(ipred_cfl_ac_422_w16_wpad3): 29861: // Copy and subsample input, padding 12 2987 vld1.16 {q0}, [r1, :128], r2 2988 vld1.16 {q2}, [r12, :128], r2 2989 vpadd.i16 d0, d0, d1 2990 vpadd.i16 d1, d4, d5 2991 vshl.i16 q0, q0, #2 2992 vdup.16 q3, d1[3] 2993 vdup.16 q1, d0[3] 2994 vdup.16 d5, d1[3] 2995 vmov d4, d1 2996 vdup.16 d1, d0[3] 2997 subs r8, r8, #2 2998 vst1.16 {q0, q1}, [r0, :128]! 2999 vaddw.u16 q8, q8, d0 3000 vaddw.u16 q9, q9, d1 3001 vaddw.u16 q10, q10, d2 3002 vaddw.u16 q11, q11, d3 3003 vst1.16 {q2, q3}, [r0, :128]! 3004 vaddw.u16 q8, q8, d4 3005 vaddw.u16 q9, q9, d5 3006 vaddw.u16 q10, q10, d6 3007 vaddw.u16 q11, q11, d7 3008 bgt 1b 3009 cmp r4, #0 3010 vmov q0, q2 3011 vmov q1, q3 3012 b L(ipred_cfl_ac_420_w16_hpad) 3013endfunc 3014 3015// void cfl_ac_444_16bpc_neon(int16_t *const ac, const pixel *const ypx, 3016// const ptrdiff_t stride, const int w_pad, 3017// const int h_pad, const int cw, const int ch); 3018function ipred_cfl_ac_444_16bpc_neon, export=1 3019 push {r4-r8,lr} 3020 ldrd r4, r5, [sp, #24] 3021 ldr r6, [sp, #32] 3022 clz r8, r5 3023 lsl r4, r4, #2 3024 adr r7, L(ipred_cfl_ac_444_tbl) 3025 sub r8, r8, #26 3026 ldr r8, [r7, r8, lsl #2] 3027 vmov.i16 q8, #0 3028 vmov.i16 q9, #0 3029 vmov.i16 q10, #0 3030 vmov.i16 q11, #0 3031 add r7, r7, r8 3032 sub r8, r6, r4 // height - h_pad 3033 rbit lr, r5 // rbit(width) 3034 rbit r12, r6 // rbit(height) 3035 clz lr, lr // ctz(width) 3036 clz r12, r12 // ctz(height) 3037 add lr, lr, r12 // log2sz 3038 add r12, r1, r2 3039 vdup.32 d31, lr 3040 lsl r2, r2, #1 3041 vneg.s32 d31, d31 // -log2sz 3042 bx r7 3043 3044 .align 2 3045L(ipred_cfl_ac_444_tbl): 3046 .word L(ipred_cfl_ac_444_w32) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB 3047 .word L(ipred_cfl_ac_444_w16) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB 3048 .word L(ipred_cfl_ac_444_w8) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB 3049 .word L(ipred_cfl_ac_444_w4) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB 3050 3051L(ipred_cfl_ac_444_w4): 30521: // Copy and expand input 3053 vld1.16 {d0}, [r1, :64], r2 3054 vld1.16 {d1}, [r12, :64], r2 3055 vld1.16 {d2}, [r1, :64], r2 3056 vld1.16 {d3}, [r12, :64], r2 3057 vshl.i16 q0, q0, #3 3058 vshl.i16 q1, q1, #3 3059 subs r8, r8, #4 3060 vst1.16 {q0, q1}, [r0, :128]! 3061 vaddw.u16 q8, q8, d0 3062 vaddw.u16 q9, q9, d1 3063 vaddw.u16 q10, q10, d2 3064 vaddw.u16 q11, q11, d3 3065 bgt 1b 3066 cmp r4, #0 3067 vmov d0, d3 3068 vmov d1, d3 3069 vmov d2, d3 3070 b L(ipred_cfl_ac_420_w4_hpad) 3071 3072L(ipred_cfl_ac_444_w8): 30731: // Copy and expand input 3074 vld1.16 {q0}, [r1, :128], r2 3075 vld1.16 {q1}, [r12, :128], r2 3076 vld1.16 {q2}, [r1, :128], r2 3077 vld1.16 {q3}, [r12, :128], r2 3078 vshl.i16 q0, q0, #3 3079 vshl.i16 q1, q1, #3 3080 vshl.i16 q2, q2, #3 3081 vshl.i16 q3, q3, #3 3082 subs r8, r8, #4 3083 vst1.16 {q0, q1}, [r0, :128]! 3084 vaddw.u16 q8, q8, d0 3085 vaddw.u16 q9, q9, d1 3086 vaddw.u16 q10, q10, d2 3087 vaddw.u16 q11, q11, d3 3088 vst1.16 {q2, q3}, [r0, :128]! 3089 vaddw.u16 q8, q8, d4 3090 vaddw.u16 q9, q9, d5 3091 vaddw.u16 q10, q10, d6 3092 vaddw.u16 q11, q11, d7 3093 bgt 1b 3094 cmp r4, #0 3095 vmov q0, q3 3096 vmov q1, q3 3097 b L(ipred_cfl_ac_420_w8_hpad) 3098 3099L(ipred_cfl_ac_444_w16): 3100 cmp r3, #0 3101 bne L(ipred_cfl_ac_444_w16_wpad) 31021: // Copy and expand input, without padding 3103 vld1.16 {q0, q1}, [r1, :128], r2 3104 vld1.16 {q2, q3}, [r12, :128], r2 3105 vshl.i16 q0, q0, #3 3106 vshl.i16 q1, q1, #3 3107 vshl.i16 q2, q2, #3 3108 vshl.i16 q3, q3, #3 3109 subs r8, r8, #2 3110 vst1.16 {q0, q1}, [r0, :128]! 3111 vaddw.u16 q8, q8, d0 3112 vaddw.u16 q9, q9, d1 3113 vaddw.u16 q10, q10, d2 3114 vaddw.u16 q11, q11, d3 3115 vst1.16 {q2, q3}, [r0, :128]! 3116 vaddw.u16 q8, q8, d4 3117 vaddw.u16 q9, q9, d5 3118 vaddw.u16 q10, q10, d6 3119 vaddw.u16 q11, q11, d7 3120 bgt 1b 3121 cmp r4, #0 3122 vmov q0, q2 3123 vmov q1, q3 3124 b L(ipred_cfl_ac_420_w16_hpad) 3125 3126L(ipred_cfl_ac_444_w16_wpad): 31271: // Copy and expand input, padding 8 3128 vld1.16 {q0}, [r1, :128], r2 3129 vld1.16 {q2}, [r12, :128], r2 3130 vshl.i16 q0, q0, #3 3131 vshl.i16 q2, q2, #3 3132 vdup.16 q1, d1[3] 3133 vdup.16 q3, d5[3] 3134 subs r8, r8, #2 3135 vst1.16 {q0, q1}, [r0, :128]! 3136 vaddw.u16 q8, q8, d0 3137 vaddw.u16 q9, q9, d1 3138 vaddw.u16 q10, q10, d2 3139 vaddw.u16 q11, q11, d3 3140 vst1.16 {q2, q3}, [r0, :128]! 3141 vaddw.u16 q8, q8, d4 3142 vaddw.u16 q9, q9, d5 3143 vaddw.u16 q10, q10, d6 3144 vaddw.u16 q11, q11, d7 3145 bgt 1b 3146 cmp r4, #0 3147 vmov q0, q2 3148 vmov q1, q3 3149 b L(ipred_cfl_ac_420_w16_hpad) 3150 3151L(ipred_cfl_ac_444_w32): 3152 adr r7, L(ipred_cfl_ac_444_w32_tbl) 3153 ldr r3, [r7, r3, lsl #1] // (w3>>1) << 2 3154 asr r2, r2, #1 3155 add r7, r7, r3 3156 bx r7 3157 3158 .align 2 3159L(ipred_cfl_ac_444_w32_tbl): 3160 .word L(ipred_cfl_ac_444_w32_wpad0) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB 3161 .word L(ipred_cfl_ac_444_w32_wpad2) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB 3162 .word L(ipred_cfl_ac_444_w32_wpad4) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB 3163 .word L(ipred_cfl_ac_444_w32_wpad6) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB 3164 3165L(ipred_cfl_ac_444_w32_wpad0): 3166 sub r2, r2, #32 31671: // Copy and expand input, without padding 3168 vld1.16 {q0, q1}, [r1, :128]! 3169 vld1.16 {q2, q3}, [r1, :128], r2 3170 vshl.i16 q0, q0, #3 3171 vshl.i16 q1, q1, #3 3172 vshl.i16 q2, q2, #3 3173 vshl.i16 q3, q3, #3 3174 subs r8, r8, #1 3175 vst1.16 {q0, q1}, [r0, :128]! 3176 vaddw.u16 q8, q8, d0 3177 vaddw.u16 q9, q9, d1 3178 vaddw.u16 q10, q10, d2 3179 vaddw.u16 q11, q11, d3 3180 vst1.16 {q2, q3}, [r0, :128]! 3181 vaddw.u16 q8, q8, d4 3182 vaddw.u16 q9, q9, d5 3183 vaddw.u16 q10, q10, d6 3184 vaddw.u16 q11, q11, d7 3185 bgt 1b 3186 cmp r4, #0 3187 b L(ipred_cfl_ac_444_w32_hpad) 3188 3189L(ipred_cfl_ac_444_w32_wpad2): 3190 sub r2, r2, #32 31911: // Copy and expand input, padding 8 3192 vld1.16 {q0, q1}, [r1, :128]! 3193 vld1.16 {q2}, [r1, :128], r2 3194 vshl.i16 q0, q0, #3 3195 vshl.i16 q1, q1, #3 3196 vshl.i16 q2, q2, #3 3197 subs r8, r8, #1 3198 vst1.16 {q0, q1}, [r0, :128]! 3199 vdup.16 q3, d5[3] 3200 vaddw.u16 q8, q8, d0 3201 vaddw.u16 q9, q9, d1 3202 vaddw.u16 q10, q10, d2 3203 vaddw.u16 q11, q11, d3 3204 vst1.16 {q2, q3}, [r0, :128]! 3205 vaddw.u16 q8, q8, d4 3206 vaddw.u16 q9, q9, d5 3207 vaddw.u16 q10, q10, d6 3208 vaddw.u16 q11, q11, d7 3209 bgt 1b 3210 cmp r4, #0 3211 b L(ipred_cfl_ac_444_w32_hpad) 3212 3213L(ipred_cfl_ac_444_w32_wpad4): 32141: // Copy and expand input, padding 16 3215 vld1.16 {q0, q1}, [r1, :128], r2 3216 vshl.i16 q0, q0, #3 3217 vshl.i16 q1, q1, #3 3218 subs r8, r8, #1 3219 vst1.16 {q0, q1}, [r0, :128]! 3220 vdup.16 q2, d3[3] 3221 vdup.16 q3, d3[3] 3222 vaddw.u16 q8, q8, d0 3223 vaddw.u16 q9, q9, d1 3224 vaddw.u16 q10, q10, d2 3225 vaddw.u16 q11, q11, d3 3226 vst1.16 {q2, q3}, [r0, :128]! 3227 vaddw.u16 q8, q8, d4 3228 vaddw.u16 q9, q9, d5 3229 vaddw.u16 q10, q10, d6 3230 vaddw.u16 q11, q11, d7 3231 bgt 1b 3232 cmp r4, #0 3233 b L(ipred_cfl_ac_444_w32_hpad) 3234 3235L(ipred_cfl_ac_444_w32_wpad6): 32361: // Copy and expand input, padding 24 3237 vld1.16 {q0}, [r1, :128], r2 3238 vshl.i16 q0, q0, #3 3239 subs r8, r8, #1 3240 vdup.16 q1, d1[3] 3241 vst1.16 {q0, q1}, [r0, :128]! 3242 vdup.16 q2, d1[3] 3243 vdup.16 q3, d1[3] 3244 vaddw.u16 q8, q8, d0 3245 vaddw.u16 q9, q9, d1 3246 vaddw.u16 q10, q10, d2 3247 vaddw.u16 q11, q11, d3 3248 vst1.16 {q2, q3}, [r0, :128]! 3249 vaddw.u16 q8, q8, d4 3250 vaddw.u16 q9, q9, d5 3251 vaddw.u16 q10, q10, d6 3252 vaddw.u16 q11, q11, d7 3253 bgt 1b 3254 cmp r4, #0 3255 3256L(ipred_cfl_ac_444_w32_hpad): 3257 beq 3f // This assumes that all callers already did "cmp r4, #0" 32582: // Vertical padding (h_pad > 0) 3259 subs r4, r4, #1 3260 vst1.16 {q0, q1}, [r0, :128]! 3261 vaddw.u16 q8, q8, d0 3262 vaddw.u16 q9, q9, d1 3263 vaddw.u16 q10, q10, d2 3264 vaddw.u16 q11, q11, d3 3265 vst1.16 {q2, q3}, [r0, :128]! 3266 vaddw.u16 q8, q8, d4 3267 vaddw.u16 q9, q9, d5 3268 vaddw.u16 q10, q10, d6 3269 vaddw.u16 q11, q11, d7 3270 bgt 2b 32713: 3272 3273 // Multiply the height by eight and reuse the w4 subtracting 3274 lsl r6, r6, #3 3275 b L(ipred_cfl_ac_420_w4_calc_subtract_dc) 3276endfunc 3277