1/* 2 * Copyright © 2018, VideoLAN and dav1d authors 3 * Copyright © 2020, Martin Storsjo 4 * Copyright © 2019, B Krishnan Iyer 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_8bpc_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); 36function ipred_dc_128_8bpc_neon, export=1 37 push {r4, lr} 38 ldr r4, [sp, #8] 39 clz r3, r3 40 adr r2, L(ipred_dc_128_tbl) 41 sub r3, r3, #25 42 ldr r3, [r2, r3, lsl #2] 43 vmov.i8 q0, #128 44 add r2, r2, r3 45 add r12, r0, r1 46 lsl r1, r1, #1 47 bx r2 48 49 .align 2 50L(ipred_dc_128_tbl): 51 .word 640f - L(ipred_dc_128_tbl) + CONFIG_THUMB 52 .word 320f - L(ipred_dc_128_tbl) + CONFIG_THUMB 53 .word 16f - L(ipred_dc_128_tbl) + CONFIG_THUMB 54 .word 8f - L(ipred_dc_128_tbl) + CONFIG_THUMB 55 .word 4f - L(ipred_dc_128_tbl) + CONFIG_THUMB 564: 57 vst1.32 {d0[0]}, [r0, :32], r1 58 vst1.32 {d0[0]}, [r12, :32], r1 59 subs r4, r4, #4 60 vst1.32 {d0[0]}, [r0, :32], r1 61 vst1.32 {d0[0]}, [r12, :32], r1 62 bgt 4b 63 pop {r4, pc} 648: 65 vst1.8 {d0}, [r0, :64], r1 66 vst1.8 {d0}, [r12, :64], r1 67 subs r4, r4, #4 68 vst1.8 {d0}, [r0, :64], r1 69 vst1.8 {d0}, [r12, :64], r1 70 bgt 8b 71 pop {r4, pc} 7216: 73 vst1.8 {d0, d1}, [r0, :128], r1 74 vst1.8 {d0, d1}, [r12, :128], r1 75 subs r4, r4, #4 76 vst1.8 {d0, d1}, [r0, :128], r1 77 vst1.8 {d0, d1}, [r12, :128], r1 78 bgt 16b 79 pop {r4, pc} 80320: 81 vmov.i8 q1, #128 8232: 83 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 84 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 85 subs r4, r4, #4 86 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 87 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 88 bgt 32b 89 pop {r4, pc} 90640: 91 vmov.i8 q1, #128 92 sub r1, r1, #32 9364: 94 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 95 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 96 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 97 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 98 subs r4, r4, #4 99 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 100 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 101 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 102 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 103 bgt 64b 104 pop {r4, pc} 105endfunc 106 107// void ipred_v_8bpc_neon(pixel *dst, const ptrdiff_t stride, 108// const pixel *const topleft, 109// const int width, const int height, const int a, 110// const int max_width, const int max_height); 111function ipred_v_8bpc_neon, export=1 112 push {r4, lr} 113 ldr lr, [sp, #8] 114 clz r3, r3 115 adr r4, L(ipred_v_tbl) 116 sub r3, r3, #25 117 ldr r3, [r4, r3, lsl #2] 118 add r2, r2, #1 119 add r4, r4, r3 120 add r12, r0, r1 121 lsl r1, r1, #1 122 bx r4 123 124 .align 2 125L(ipred_v_tbl): 126 .word 640f - L(ipred_v_tbl) + CONFIG_THUMB 127 .word 320f - L(ipred_v_tbl) + CONFIG_THUMB 128 .word 160f - L(ipred_v_tbl) + CONFIG_THUMB 129 .word 80f - L(ipred_v_tbl) + CONFIG_THUMB 130 .word 40f - L(ipred_v_tbl) + CONFIG_THUMB 13140: 132 vld1.32 {d0[]}, [r2] 1334: 134 vst1.32 {d0[0]}, [r0, :32], r1 135 vst1.32 {d0[0]}, [r12, :32], r1 136 subs lr, lr, #4 137 vst1.32 {d0[0]}, [r0, :32], r1 138 vst1.32 {d0[0]}, [r12, :32], r1 139 bgt 4b 140 pop {r4, pc} 14180: 142 vld1.8 {d0}, [r2] 1438: 144 vst1.8 {d0}, [r0, :64], r1 145 vst1.8 {d0}, [r12, :64], r1 146 subs lr, lr, #4 147 vst1.8 {d0}, [r0, :64], r1 148 vst1.8 {d0}, [r12, :64], r1 149 bgt 8b 150 pop {r4, pc} 151160: 152 vld1.8 {q0}, [r2] 15316: 154 vst1.8 {d0, d1}, [r0, :128], r1 155 vst1.8 {d0, d1}, [r12, :128], r1 156 subs lr, lr, #4 157 vst1.8 {d0, d1}, [r0, :128], r1 158 vst1.8 {d0, d1}, [r12, :128], r1 159 bgt 16b 160 pop {r4, pc} 161320: 162 vld1.8 {q0, q1}, [r2] 16332: 164 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 165 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 166 subs lr, lr, #4 167 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 168 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 169 bgt 32b 170 pop {r4, pc} 171640: 172 vld1.8 {q0, q1}, [r2]! 173 sub r1, r1, #32 174 vld1.8 {q2, q3}, [r2] 17564: 176 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 177 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 178 vst1.8 {d4, d5, d6, d7}, [r0, :128], r1 179 vst1.8 {d4, d5, d6, d7}, [r12, :128], r1 180 subs lr, lr, #4 181 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 182 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 183 vst1.8 {d4, d5, d6, d7}, [r0, :128], r1 184 vst1.8 {d4, d5, d6, d7}, [r12, :128], r1 185 bgt 64b 186 pop {r4, pc} 187endfunc 188 189// void ipred_h_8bpc_neon(pixel *dst, const ptrdiff_t stride, 190// const pixel *const topleft, 191// const int width, const int height, const int a, 192// const int max_width, const int max_height); 193function ipred_h_8bpc_neon, export=1 194 push {r4-r5, lr} 195 ldr r4, [sp, #12] 196 clz r3, r3 197 adr r5, L(ipred_h_tbl) 198 sub r3, r3, #25 199 ldr r3, [r5, r3, lsl #2] 200 sub r2, r2, #4 201 mov lr, #-4 202 add r5, r5, r3 203 add r12, r0, r1 204 lsl r1, r1, #1 205 bx r5 206 207 .align 2 208L(ipred_h_tbl): 209 .word 640f - L(ipred_h_tbl) + CONFIG_THUMB 210 .word 320f - L(ipred_h_tbl) + CONFIG_THUMB 211 .word 160f - L(ipred_h_tbl) + CONFIG_THUMB 212 .word 8f - L(ipred_h_tbl) + CONFIG_THUMB 213 .word 4f - L(ipred_h_tbl) + CONFIG_THUMB 2144: 215 vld4.8 {d0[], d1[], d2[], d3[]}, [r2, :32], lr 216 vst1.32 {d3[0]}, [r0, :32], r1 217 vst1.32 {d2[0]}, [r12, :32], r1 218 subs r4, r4, #4 219 vst1.32 {d1[0]}, [r0, :32], r1 220 vst1.32 {d0[0]}, [r12, :32], r1 221 bgt 4b 222 pop {r4-r5, pc} 2238: 224 vld4.8 {d0[], d1[], d2[], d3[]}, [r2, :32], lr 225 vst1.8 {d3}, [r0, :64], r1 226 vst1.8 {d2}, [r12, :64], r1 227 subs r4, r4, #4 228 vst1.8 {d1}, [r0, :64], r1 229 vst1.8 {d0}, [r12, :64], r1 230 bgt 8b 231 pop {r4-r5, pc} 232160: 233 add r2, r2, #3 234 mov lr, #-1 23516: 236 vld1.8 {d0[], d1[]}, [r2], lr 237 subs r4, r4, #4 238 vld1.8 {d2[], d3[]}, [r2], lr 239 vst1.8 {q0}, [r0, :128], r1 240 vld1.8 {d4[], d5[]}, [r2], lr 241 vst1.8 {q1}, [r12, :128], r1 242 vld1.8 {d6[], d7[]}, [r2], lr 243 vst1.8 {q2}, [r0, :128], r1 244 vst1.8 {q3}, [r12, :128], r1 245 bgt 16b 246 pop {r4-r5, pc} 247320: 248 add r2, r2, #3 249 mov lr, #-1 250 sub r1, r1, #16 25132: 252 vld1.8 {d0[], d1[]}, [r2], lr 253 subs r4, r4, #4 254 vld1.8 {d2[], d3[]}, [r2], lr 255 vst1.8 {q0}, [r0, :128]! 256 vld1.8 {d4[], d5[]}, [r2], lr 257 vst1.8 {q1}, [r12, :128]! 258 vld1.8 {d6[], d7[]}, [r2], lr 259 vst1.8 {q0}, [r0, :128], r1 260 vst1.8 {q1}, [r12, :128], r1 261 vst1.8 {q2}, [r0, :128]! 262 vst1.8 {q3}, [r12, :128]! 263 vst1.8 {q2}, [r0, :128], r1 264 vst1.8 {q3}, [r12, :128], r1 265 bgt 32b 266 pop {r4-r5, pc} 267640: 268 add r2, r2, #3 269 mov lr, #-1 270 sub r1, r1, #48 27164: 272 vld1.8 {d0[], d1[]}, [r2], lr 273 subs r4, r4, #4 274 vld1.8 {d2[], d3[]}, [r2], lr 275 vst1.8 {q0}, [r0, :128]! 276 vld1.8 {d4[], d5[]}, [r2], lr 277 vst1.8 {q1}, [r12, :128]! 278 vld1.8 {d6[], d7[]}, [r2], lr 279 vst1.8 {q0}, [r0, :128]! 280 vst1.8 {q1}, [r12, :128]! 281 vst1.8 {q0}, [r0, :128]! 282 vst1.8 {q1}, [r12, :128]! 283 vst1.8 {q0}, [r0, :128], r1 284 vst1.8 {q1}, [r12, :128], r1 285 vst1.8 {q2}, [r0, :128]! 286 vst1.8 {q3}, [r12, :128]! 287 vst1.8 {q2}, [r0, :128]! 288 vst1.8 {q3}, [r12, :128]! 289 vst1.8 {q2}, [r0, :128]! 290 vst1.8 {q3}, [r12, :128]! 291 vst1.8 {q2}, [r0, :128], r1 292 vst1.8 {q3}, [r12, :128], r1 293 bgt 64b 294 pop {r4-r5, pc} 295endfunc 296 297// void ipred_dc_top_8bpc_neon(pixel *dst, const ptrdiff_t stride, 298// const pixel *const topleft, 299// const int width, const int height, const int a, 300// const int max_width, const int max_height); 301function ipred_dc_top_8bpc_neon, export=1 302 push {r4-r5, lr} 303 ldr r4, [sp, #12] 304 clz r3, r3 305 adr r5, L(ipred_dc_top_tbl) 306 sub r3, r3, #25 307 ldr r3, [r5, r3, lsl #2] 308 add r2, r2, #1 309 add r5, r5, r3 310 add r12, r0, r1 311 lsl r1, r1, #1 312 bx r5 313 314 .align 2 315L(ipred_dc_top_tbl): 316 .word 640f - L(ipred_dc_top_tbl) + CONFIG_THUMB 317 .word 320f - L(ipred_dc_top_tbl) + CONFIG_THUMB 318 .word 160f - L(ipred_dc_top_tbl) + CONFIG_THUMB 319 .word 80f - L(ipred_dc_top_tbl) + CONFIG_THUMB 320 .word 40f - L(ipred_dc_top_tbl) + CONFIG_THUMB 32140: 322 vld1.32 {d0[]}, [r2] 323 vpaddl.u8 d0, d0 324 vpadd.u16 d0, d0 325 vrshrn.u16 d0, q0, #2 326 vdup.8 d0, d0[0] 3274: 328 vst1.32 {d0[0]}, [r0, :32], r1 329 vst1.32 {d0[0]}, [r12, :32], r1 330 subs r4, r4, #4 331 vst1.32 {d0[0]}, [r0, :32], r1 332 vst1.32 {d0[0]}, [r12, :32], r1 333 bgt 4b 334 pop {r4-r5, pc} 33580: 336 vld1.8 {d0}, [r2] 337 vpaddl.u8 d0, d0 338 vpadd.u16 d0, d0 339 vpadd.u16 d0, d0 340 vrshrn.u16 d0, q0, #3 341 vdup.8 d0, d0[0] 3428: 343 vst1.8 {d0}, [r0, :64], r1 344 vst1.8 {d0}, [r12, :64], r1 345 subs r4, r4, #4 346 vst1.8 {d0}, [r0, :64], r1 347 vst1.8 {d0}, [r12, :64], r1 348 bgt 8b 349 pop {r4-r5, pc} 350160: 351 vld1.8 {d0, d1}, [r2] 352 vaddl.u8 q0, d0, d1 353 vadd.u16 d0, d0, d1 354 vpadd.u16 d0, d0 355 vpadd.u16 d0, d0 356 vrshrn.u16 d0, q0, #4 357 vdup.8 q0, d0[0] 35816: 359 vst1.8 {d0, d1}, [r0, :128], r1 360 vst1.8 {d0, d1}, [r12, :128], r1 361 subs r4, r4, #4 362 vst1.8 {d0, d1}, [r0, :128], r1 363 vst1.8 {d0, d1}, [r12, :128], r1 364 bgt 16b 365 pop {r4-r5, pc} 366320: 367 vld1.8 {d0, d1, d2, d3}, [r2] 368 vaddl.u8 q0, d0, d1 369 vaddl.u8 q1, d2, d3 370 vadd.u16 q0, q0, q1 371 vadd.u16 d0, d0, d1 372 vpadd.u16 d0, d0 373 vpadd.u16 d0, d0 374 vrshrn.u16 d4, q0, #5 375 vdup.8 q0, d4[0] 376 vdup.8 q1, d4[0] 37732: 378 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 379 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 380 subs r4, r4, #4 381 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 382 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 383 bgt 32b 384 pop {r4-r5, pc} 385640: 386 vld1.8 {d0, d1, d2, d3}, [r2]! 387 vaddl.u8 q0, d0, d1 388 vld1.8 {d4, d5, d6, d7}, [r2] 389 vaddl.u8 q1, d2, d3 390 vaddl.u8 q2, d4, d5 391 vaddl.u8 q3, d6, d7 392 vadd.u16 q0, q0, q1 393 vadd.u16 q1, q2, q3 394 vadd.u16 q0, q0, q1 395 vadd.u16 d0, d0, d1 396 vpadd.u16 d0, d0 397 vpadd.u16 d0, d0 398 vrshrn.u16 d18, q0, #6 399 vdup.8 q0, d18[0] 400 vdup.8 q1, d18[0] 401 sub r1, r1, #32 40264: 403 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 404 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 405 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 406 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 407 subs r4, r4, #4 408 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 409 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 410 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 411 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 412 bgt 64b 413 pop {r4-r5, pc} 414endfunc 415 416// void ipred_dc_left_8bpc_neon(pixel *dst, const ptrdiff_t stride, 417// const pixel *const topleft, 418// const int width, const int height, const int a, 419// const int max_width, const int max_height); 420function ipred_dc_left_8bpc_neon, export=1 421 push {r4-r5, lr} 422 ldr r4, [sp, #12] 423 sub r2, r2, r4 424 clz r3, r3 425 clz lr, r4 426 sub lr, lr, #25 427 adr r5, L(ipred_dc_left_tbl) 428 sub r3, r3, #20 429 ldr r3, [r5, r3, lsl #2] 430 ldr lr, [r5, lr, lsl #2] 431 add r3, r5, r3 432 add r5, r5, lr 433 add r12, r0, r1 434 lsl r1, r1, #1 435 bx r5 436 437 .align 2 438L(ipred_dc_left_tbl): 439 .word L(ipred_dc_left_h64) - L(ipred_dc_left_tbl) + CONFIG_THUMB 440 .word L(ipred_dc_left_h32) - L(ipred_dc_left_tbl) + CONFIG_THUMB 441 .word L(ipred_dc_left_h16) - L(ipred_dc_left_tbl) + CONFIG_THUMB 442 .word L(ipred_dc_left_h8) - L(ipred_dc_left_tbl) + CONFIG_THUMB 443 .word L(ipred_dc_left_h4) - L(ipred_dc_left_tbl) + CONFIG_THUMB 444 .word L(ipred_dc_left_w64) - L(ipred_dc_left_tbl) + CONFIG_THUMB 445 .word L(ipred_dc_left_w32) - L(ipred_dc_left_tbl) + CONFIG_THUMB 446 .word L(ipred_dc_left_w16) - L(ipred_dc_left_tbl) + CONFIG_THUMB 447 .word L(ipred_dc_left_w8) - L(ipred_dc_left_tbl) + CONFIG_THUMB 448 .word L(ipred_dc_left_w4) - L(ipred_dc_left_tbl) + CONFIG_THUMB 449 450L(ipred_dc_left_h4): 451 vld1.32 {d0[]}, [r2, :32] 452 vpaddl.u8 d0, d0 453 vpadd.u16 d0, d0 454 vrshrn.u16 d0, q0, #2 455 vdup.8 q0, d0[0] 456 bx r3 457L(ipred_dc_left_w4): 458 vst1.32 {d0[0]}, [r0, :32], r1 459 vst1.32 {d0[0]}, [r12, :32], r1 460 subs r4, r4, #4 461 vst1.32 {d0[0]}, [r0, :32], r1 462 vst1.32 {d0[0]}, [r12, :32], r1 463 bgt L(ipred_dc_left_w4) 464 pop {r4-r5, pc} 465L(ipred_dc_left_h8): 466 vld1.8 {d0}, [r2, :64] 467 vpaddl.u8 d0, d0 468 vpadd.u16 d0, d0 469 vpadd.u16 d0, d0 470 vrshrn.u16 d0, q0, #3 471 vdup.8 q0, d0[0] 472 bx r3 473L(ipred_dc_left_w8): 474 vst1.8 {d0}, [r0, :64], r1 475 vst1.8 {d0}, [r12, :64], r1 476 subs r4, r4, #4 477 vst1.8 {d0}, [r0, :64], r1 478 vst1.8 {d0}, [r12, :64], r1 479 bgt L(ipred_dc_left_w8) 480 pop {r4-r5, pc} 481L(ipred_dc_left_h16): 482 vld1.8 {d0, d1}, [r2, :128] 483 vaddl.u8 q0, d0, d1 484 vadd.u16 d0, d0, d1 485 vpadd.u16 d0, d0 486 vpadd.u16 d0, d0 487 vrshrn.u16 d0, q0, #4 488 vdup.8 q0, d0[0] 489 bx r3 490L(ipred_dc_left_w16): 491 vst1.8 {d0, d1}, [r0, :128], r1 492 vst1.8 {d0, d1}, [r12, :128], r1 493 subs r4, r4, #4 494 vst1.8 {d0, d1}, [r0, :128], r1 495 vst1.8 {d0, d1}, [r12, :128], r1 496 bgt L(ipred_dc_left_w16) 497 pop {r4-r5, pc} 498L(ipred_dc_left_h32): 499 vld1.8 {d0, d1, d2, d3}, [r2, :128] 500 vaddl.u8 q0, d0, d1 501 vaddl.u8 q1, d2, d3 502 vadd.u16 q0, q0, q1 503 vadd.u16 d0, d0, d1 504 vpadd.u16 d0, d0 505 vpadd.u16 d0, d0 506 vrshrn.u16 d0, q0, #5 507 vdup.8 q0, d0[0] 508 bx r3 509L(ipred_dc_left_w32): 510 vmov.8 q1, q0 5111: 512 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 513 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 514 subs r4, r4, #4 515 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 516 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 517 bgt 1b 518 pop {r4-r5, pc} 519L(ipred_dc_left_h64): 520 vld1.8 {d0, d1, d2, d3}, [r2, :128]! 521 vld1.8 {d4, d5, d6, d7}, [r2, :128] 522 vaddl.u8 q0, d0, d1 523 vaddl.u8 q1, d2, d3 524 vaddl.u8 q2, d4, d5 525 vaddl.u8 q3, d6, d7 526 vadd.u16 q0, q0, q1 527 vadd.u16 q1, q2, q3 528 vadd.u16 q0, q0, q1 529 vadd.u16 d0, d0, d1 530 vpadd.u16 d0, d0 531 vpadd.u16 d0, d0 532 vrshrn.u16 d0, q0, #6 533 vdup.8 q0, d0[0] 534 bx r3 535L(ipred_dc_left_w64): 536 vmov.8 q1, q0 537 sub r1, r1, #32 5381: 539 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 540 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 541 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 542 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 543 subs r4, r4, #4 544 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 545 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 546 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 547 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 548 bgt 1b 549 pop {r4-r5, pc} 550endfunc 551 552// void ipred_dc_8bpc_neon(pixel *dst, const ptrdiff_t stride, 553// const pixel *const topleft, 554// const int width, const int height, const int a, 555// const int max_width, const int max_height); 556function ipred_dc_8bpc_neon, export=1 557 push {r4-r6, lr} 558 ldr r4, [sp, #16] 559 sub r2, r2, r4 560 add lr, r3, r4 // width + height 561 clz r3, r3 562 clz r12, r4 563 vdup.16 q15, lr // width + height 564 adr r5, L(ipred_dc_tbl) 565 rbit lr, lr // rbit(width + height) 566 sub r3, r3, #20 // 25 leading bits, minus table offset 5 567 sub r12, r12, #25 568 clz lr, lr // ctz(width + height) 569 ldr r3, [r5, r3, lsl #2] 570 ldr r12, [r5, r12, lsl #2] 571 neg lr, lr // -ctz(width + height) 572 add r3, r5, r3 573 add r5, r5, r12 574 vshr.u16 q15, q15, #1 // (width + height) >> 1 575 vdup.16 q14, lr // -ctz(width + height) 576 add r12, r0, r1 577 lsl r1, r1, #1 578 bx r5 579 580 .align 2 581L(ipred_dc_tbl): 582 .word L(ipred_dc_h64) - L(ipred_dc_tbl) + CONFIG_THUMB 583 .word L(ipred_dc_h32) - L(ipred_dc_tbl) + CONFIG_THUMB 584 .word L(ipred_dc_h16) - L(ipred_dc_tbl) + CONFIG_THUMB 585 .word L(ipred_dc_h8) - L(ipred_dc_tbl) + CONFIG_THUMB 586 .word L(ipred_dc_h4) - L(ipred_dc_tbl) + CONFIG_THUMB 587 .word L(ipred_dc_w64) - L(ipred_dc_tbl) + CONFIG_THUMB 588 .word L(ipred_dc_w32) - L(ipred_dc_tbl) + CONFIG_THUMB 589 .word L(ipred_dc_w16) - L(ipred_dc_tbl) + CONFIG_THUMB 590 .word L(ipred_dc_w8) - L(ipred_dc_tbl) + CONFIG_THUMB 591 .word L(ipred_dc_w4) - L(ipred_dc_tbl) + CONFIG_THUMB 592 593L(ipred_dc_h4): 594 vld1.32 {d0[]}, [r2, :32]! 595 vpaddl.u8 d0, d0 596 add r2, r2, #1 597 vpadd.u16 d0, d0 598 bx r3 599L(ipred_dc_w4): 600 vld1.32 {d1[]}, [r2] 601 vadd.s16 d0, d0, d30 602 vpaddl.u8 d1, d1 603 vpadd.u16 d1, d1 604 cmp r4, #4 605 vadd.s16 d0, d0, d1 606 vshl.u16 d0, d0, d28 607 beq 1f 608 // h = 8/16 609 movw lr, #(0x3334/2) 610 movw r5, #(0x5556/2) 611 cmp r4, #16 612 it ne 613 movne lr, r5 614 vdup.16 d30, lr 615 vqdmulh.s16 d0, d0, d30 6161: 617 vdup.8 d0, d0[0] 6182: 619 vst1.32 {d0[0]}, [r0, :32], r1 620 vst1.32 {d0[0]}, [r12, :32], r1 621 subs r4, r4, #4 622 vst1.32 {d0[0]}, [r0, :32], r1 623 vst1.32 {d0[0]}, [r12, :32], r1 624 bgt 2b 625 pop {r4-r6, pc} 626 627L(ipred_dc_h8): 628 vld1.8 {d0}, [r2, :64]! 629 vpaddl.u8 d0, d0 630 vpadd.u16 d0, d0 631 add r2, r2, #1 632 vpadd.u16 d0, d0 633 bx r3 634L(ipred_dc_w8): 635 vld1.8 {d2}, [r2] 636 vadd.s16 d0, d0, d30 637 vpaddl.u8 d2, d2 638 vpadd.u16 d2, d2 639 vpadd.u16 d2, d2 640 cmp r4, #8 641 vadd.s16 d0, d0, d2 642 vshl.u16 d0, d0, d28 643 beq 1f 644 // h = 4/16/32 645 cmp r4, #32 646 movw lr, #(0x3334/2) 647 movw r5, #(0x5556/2) 648 it ne 649 movne lr, r5 650 vdup.16 d24, lr 651 vqdmulh.s16 d0, d0, d24 6521: 653 vdup.8 d0, d0[0] 6542: 655 vst1.8 {d0}, [r0, :64], r1 656 vst1.8 {d0}, [r12, :64], r1 657 subs r4, r4, #4 658 vst1.8 {d0}, [r0, :64], r1 659 vst1.8 {d0}, [r12, :64], r1 660 bgt 2b 661 pop {r4-r6, pc} 662 663L(ipred_dc_h16): 664 vld1.8 {d0, d1}, [r2, :128]! 665 vaddl.u8 q0, d0, d1 666 vadd.u16 d0, d0, d1 667 vpadd.u16 d0, d0 668 add r2, r2, #1 669 vpadd.u16 d0, d0 670 bx r3 671L(ipred_dc_w16): 672 vld1.8 {d2, d3}, [r2] 673 vadd.s16 d0, d0, d30 674 vaddl.u8 q1, d2, d3 675 vadd.u16 d2, d2, d3 676 vpadd.u16 d2, d2 677 vpadd.u16 d2, d2 678 cmp r4, #16 679 vadd.s16 d0, d0, d2 680 vshl.u16 d0, d0, d28 681 beq 1f 682 // h = 4/8/32/64 683 tst r4, #(32+16+8) // 16 added to make a consecutive bitmask 684 movw lr, #(0x3334/2) 685 movw r5, #(0x5556/2) 686 it ne 687 movne lr, r5 688 vdup.16 d24, lr 689 vqdmulh.s16 d0, d0, d24 6901: 691 vdup.8 q0, d0[0] 6922: 693 vst1.8 {d0, d1}, [r0, :128], r1 694 vst1.8 {d0, d1}, [r12, :128], r1 695 subs r4, r4, #4 696 vst1.8 {d0, d1}, [r0, :128], r1 697 vst1.8 {d0, d1}, [r12, :128], r1 698 bgt 2b 699 pop {r4-r6, pc} 700 701L(ipred_dc_h32): 702 vld1.8 {d0, d1, d2, d3}, [r2, :128]! 703 vaddl.u8 q0, d0, d1 704 vaddl.u8 q1, d2, d3 705 vadd.u16 q0, q0, q1 706 vadd.u16 d0, d0, d1 707 vpadd.u16 d0, d0 708 add r2, r2, #1 709 vpadd.u16 d0, d0 710 bx r3 711L(ipred_dc_w32): 712 vld1.8 {d2, d3, d4, d5}, [r2] 713 vadd.s16 d0, d0, d30 714 vaddl.u8 q1, d2, d3 715 vaddl.u8 q2, d4, d5 716 vadd.u16 q1, q1, q2 717 vadd.u16 d2, d2, d3 718 vpadd.u16 d2, d2 719 vpadd.u16 d2, d2 720 cmp r4, #32 721 vadd.s16 d0, d0, d2 722 vshl.u16 d4, d0, d28 723 beq 1f 724 // h = 8/16/64 725 cmp r4, #8 726 movw lr, #(0x3334/2) 727 movw r5, #(0x5556/2) 728 it ne 729 movne lr, r5 730 vdup.16 d24, lr 731 vqdmulh.s16 d4, d4, d24 7321: 733 vdup.8 q0, d4[0] 734 vdup.8 q1, d4[0] 7352: 736 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 737 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 738 subs r4, r4, #4 739 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 740 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 741 bgt 2b 742 pop {r4-r6, pc} 743 744L(ipred_dc_h64): 745 vld1.8 {d0, d1, d2, d3}, [r2, :128]! 746 vaddl.u8 q0, d0, d1 747 vld1.8 {d4, d5, d6, d7}, [r2, :128]! 748 vaddl.u8 q1, d2, d3 749 vaddl.u8 q2, d4, d5 750 vaddl.u8 q3, d6, d7 751 vadd.u16 q0, q0, q1 752 vadd.u16 q1, q2, q3 753 vadd.u16 q0, q0, q1 754 vadd.u16 d0, d0, d1 755 vpadd.u16 d0, d0 756 add r2, r2, #1 757 vpadd.u16 d0, d0 758 bx r3 759L(ipred_dc_w64): 760 vld1.8 {d2, d3, d4, d5}, [r2]! 761 vadd.s16 d0, d0, d30 762 vaddl.u8 q2, d4, d5 763 vaddl.u8 q1, d2, d3 764 vadd.u16 d4, d4, d5 765 vadd.u16 d2, d2, d3 766 vld1.8 {d16, d17, d18, d19}, [r2] 767 vpadd.u16 d4, d4 768 vpadd.u16 d2, d2 769 vpadd.u16 d4, d4 770 vpadd.u16 d2, d2 771 vaddl.u8 q8, d16, d17 772 vaddl.u8 q9, d18, d19 773 vadd.u16 d16, d16, d17 774 vadd.u16 d18, d18, d19 775 vpadd.u16 d16, d16 776 vpadd.u16 d18, d18 777 vpadd.u16 d16, d16 778 vpadd.u16 d18, d18 779 vadd.u16 d2, d2, d4 780 vadd.u16 d3, d16, d18 781 cmp r4, #64 782 vadd.s16 d0, d0, d2 783 vadd.s16 d0, d0, d3 784 vshl.u16 d18, d0, d28 785 beq 1f 786 // h = 16/32 787 movw lr, #(0x5556/2) 788 movt lr, #(0x3334/2) 789 and r5, r4, #31 790 lsr lr, lr, r5 791 vdup.16 d30, lr 792 vqdmulh.s16 d18, d18, d30 7931: 794 sub r1, r1, #32 795 vdup.8 q0, d18[0] 796 vdup.8 q1, d18[0] 7972: 798 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 799 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 800 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 801 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 802 subs r4, r4, #4 803 vst1.8 {d0, d1, d2, d3}, [r0, :128]! 804 vst1.8 {d0, d1, d2, d3}, [r12, :128]! 805 vst1.8 {d0, d1, d2, d3}, [r0, :128], r1 806 vst1.8 {d0, d1, d2, d3}, [r12, :128], r1 807 bgt 2b 808 pop {r4-r6, pc} 809endfunc 810 811// void ipred_paeth_8bpc_neon(pixel *dst, const ptrdiff_t stride, 812// const pixel *const topleft, 813// const int width, const int height, const int a, 814// const int max_width, const int max_height); 815function ipred_paeth_8bpc_neon, export=1 816 push {r4-r8, lr} 817 ldr r4, [sp, #24] 818 clz lr, r3 819 adr r5, L(ipred_paeth_tbl) 820 sub lr, lr, #25 821 ldr lr, [r5, lr, lsl #2] 822 vld1.8 {d4[], d5[]}, [r2] 823 add r8, r2, #1 824 sub r2, r2, #4 825 add r5, r5, lr 826 mov r7, #-4 827 add r6, r0, r1 828 lsl r1, r1, #1 829 bx r5 830 831 .align 2 832L(ipred_paeth_tbl): 833 .word 640f - L(ipred_paeth_tbl) + CONFIG_THUMB 834 .word 320f - L(ipred_paeth_tbl) + CONFIG_THUMB 835 .word 160f - L(ipred_paeth_tbl) + CONFIG_THUMB 836 .word 80f - L(ipred_paeth_tbl) + CONFIG_THUMB 837 .word 40f - L(ipred_paeth_tbl) + CONFIG_THUMB 838 83940: 840 vld1.32 {d6[], d7[]}, [r8] 841 vsubl.u8 q8, d6, d4 // top - topleft 8424: 843 vld4.8 {d0[], d1[], d2[], d3[]}, [r2, :32], r7 844 vzip.32 d0, d1 845 vzip.32 d2, d3 846 vaddw.u8 q9, q8, d0 847 vaddw.u8 q10, q8, d2 848 vqmovun.s16 d18, q9 // base 849 vqmovun.s16 d19, q10 850 vmov d1, d2 851 vabd.u8 q10, q3, q9 // tdiff 852 vabd.u8 q11, q2, q9 // tldiff 853 vabd.u8 q9, q0, q9 // ldiff 854 vmin.u8 q12, q10, q11 // min(tdiff, tldiff) 855 vcge.u8 q10, q11, q10 // tldiff >= tdiff 856 vcge.u8 q9, q12, q9 // min(tdiff, tldiff) >= ldiff 857 vbsl q10, q3, q2 // tdiff <= tldiff ? top : topleft 858 vbit q10, q0, q9 // ldiff <= min ? left : ... 859 vst1.32 {d21[1]}, [r0, :32], r1 860 vst1.32 {d21[0]}, [r6, :32], r1 861 subs r4, r4, #4 862 vst1.32 {d20[1]}, [r0, :32], r1 863 vst1.32 {d20[0]}, [r6, :32], r1 864 bgt 4b 865 pop {r4-r8, pc} 86680: 867 vld1.8 {d6}, [r8] 868 vsubl.u8 q8, d6, d4 // top - topleft 869 vmov d7, d6 8708: 871 vld4.8 {d0[], d1[], d2[], d3[]}, [r2, :32], r7 872 vaddw.u8 q9, q8, d0 873 vaddw.u8 q10, q8, d1 874 vaddw.u8 q11, q8, d2 875 vaddw.u8 q12, q8, d3 876 vqmovun.s16 d18, q9 // base 877 vqmovun.s16 d19, q10 878 vqmovun.s16 d20, q11 879 vqmovun.s16 d21, q12 880 vabd.u8 q11, q3, q9 // tdiff 881 vabd.u8 q12, q3, q10 882 vabd.u8 q13, q2, q9 // tldiff 883 vabd.u8 q14, q2, q10 884 vabd.u8 q10, q1, q10 // ldiff 885 vabd.u8 q9, q0, q9 886 vmin.u8 q15, q12, q14 // min(tdiff, tldiff) 887 vcge.u8 q12, q14, q12 // tldiff >= tdiff 888 vmin.u8 q14, q11, q13 // min(tdiff, tldiff) 889 vcge.u8 q11, q13, q11 // tldiff >= tdiff 890 vcge.u8 q10, q15, q10 // min(tdiff, tldiff) >= ldiff 891 vcge.u8 q9, q14, q9 892 vbsl q12, q3, q2 // tdiff <= tldiff ? top : topleft 893 vbsl q11, q3, q2 894 vbit q12, q1, q10 // ldiff <= min ? left : ... 895 vbit q11, q0, q9 896 vst1.8 {d25}, [r0, :64], r1 897 vst1.8 {d24}, [r6, :64], r1 898 subs r4, r4, #4 899 vst1.8 {d23}, [r0, :64], r1 900 vst1.8 {d22}, [r6, :64], r1 901 bgt 8b 902 pop {r4-r8, pc} 903160: 904320: 905640: 906 vld1.8 {d6}, [r8]! 907 mov r12, r3 908 // Set up pointers for four rows in parallel; r0, r6, r5, lr 909 add r5, r0, r1 910 add lr, r6, r1 911 lsl r1, r1, #1 912 sub r1, r1, r3 9131: 914 vld4.8 {d0[], d1[], d2[], d3[]}, [r2, :32], r7 9152: 916 vsubl.u8 q8, d6, d4 // top - topleft 917 vmov d7, d6 918 vaddw.u8 q9, q8, d0 919 vaddw.u8 q10, q8, d1 920 vaddw.u8 q11, q8, d2 921 vaddw.u8 q12, q8, d3 922 vqmovun.s16 d18, q9 // base 923 vqmovun.s16 d19, q10 924 vqmovun.s16 d20, q11 925 vqmovun.s16 d21, q12 926 vabd.u8 q11, q3, q9 // tdiff 927 vabd.u8 q12, q3, q10 928 vabd.u8 q13, q2, q9 // tldiff 929 vabd.u8 q14, q2, q10 930 vabd.u8 q10, q1, q10 // ldiff 931 vabd.u8 q9, q0, q9 932 vmin.u8 q15, q12, q14 // min(tdiff, tldiff) 933 vcge.u8 q12, q14, q12 // tldiff >= tdiff 934 vmin.u8 q14, q11, q13 // min(tdiff, tldiff) 935 vcge.u8 q11, q13, q11 // tldiff >= tdiff 936 vcge.u8 q10, q15, q10 // min(tdiff, tldiff) >= ldiff 937 vcge.u8 q9, q14, q9 938 vbsl q12, q3, q2 // tdiff <= tldiff ? top : topleft 939 vbsl q11, q3, q2 940 vbit q12, q1, q10 // ldiff <= min ? left : ... 941 vbit q11, q0, q9 942 subs r3, r3, #8 943 vst1.8 {d25}, [r0, :64]! 944 vst1.8 {d24}, [r6, :64]! 945 vst1.8 {d23}, [r5, :64]! 946 vst1.8 {d22}, [lr, :64]! 947 ble 8f 948 vld1.8 {d6}, [r8]! 949 b 2b 9508: 951 subs r4, r4, #4 952 ble 9f 953 // End of horizontal loop, move pointers to next four rows 954 sub r8, r8, r12 955 add r0, r0, r1 956 add r6, r6, r1 957 vld1.8 {d6}, [r8]! 958 add r5, r5, r1 959 add lr, lr, r1 960 mov r3, r12 961 b 1b 9629: 963 pop {r4-r8, pc} 964endfunc 965 966// void ipred_smooth_8bpc_neon(pixel *dst, const ptrdiff_t stride, 967// const pixel *const topleft, 968// const int width, const int height, const int a, 969// const int max_width, const int max_height); 970function ipred_smooth_8bpc_neon, export=1 971 push {r4-r10, lr} 972 ldr r4, [sp, #32] 973 movrel r10, X(sm_weights) 974 add r12, r10, r4 975 add r10, r10, r3 976 clz r9, r3 977 adr r5, L(ipred_smooth_tbl) 978 sub lr, r2, r4 979 sub r9, r9, #25 980 ldr r9, [r5, r9, lsl #2] 981 vld1.8 {d4[]}, [lr] // bottom 982 add r8, r2, #1 983 add r5, r5, r9 984 add r6, r0, r1 985 lsl r1, r1, #1 986 bx r5 987 988 .align 2 989L(ipred_smooth_tbl): 990 .word 640f - L(ipred_smooth_tbl) + CONFIG_THUMB 991 .word 320f - L(ipred_smooth_tbl) + CONFIG_THUMB 992 .word 160f - L(ipred_smooth_tbl) + CONFIG_THUMB 993 .word 80f - L(ipred_smooth_tbl) + CONFIG_THUMB 994 .word 40f - L(ipred_smooth_tbl) + CONFIG_THUMB 995 99640: 997 vld1.32 {d16[]}, [r8] // top 998 vld1.32 {d18[]}, [r10, :32] // weights_hor 999 sub r2, r2, #4 1000 mov r7, #-4 1001 vdup.8 q3, d16[3] // right 1002 vsubl.u8 q8, d16, d4 // top-bottom 1003 vmovl.u8 q9, d18 // weights_hor 10044: 1005 vld4.8 {d0[], d1[], d2[], d3[]}, [r2, :32], r7 // left 1006 vld4.8 {d20[], d21[], d22[], d23[]}, [r12, :32]! // weights_ver 1007 vshll.i8 q12, d6, #8 // right*256 1008 vshll.i8 q13, d6, #8 1009 vzip.32 d1, d0 // left, flipped 1010 vzip.32 d3, d2 1011 vzip.32 d20, d21 // weights_ver 1012 vzip.32 d22, d23 1013 vshll.i8 q14, d4, #8 // bottom*256 1014 vshll.i8 q15, d4, #8 1015 vsubl.u8 q0, d1, d6 // left-right 1016 vsubl.u8 q1, d3, d6 1017 vmovl.u8 q10, d20 // weights_ver 1018 vmovl.u8 q11, d22 1019 vmla.i16 q12, q1, q9 // right*256 + (left-right)*weights_hor 1020 vmla.i16 q13, q0, q9 // (left flipped) 1021 vmla.i16 q14, q8, q10 // bottom*256 + (top-bottom)*weights_ver 1022 vmla.i16 q15, q8, q11 1023 vhadd.u16 q12, q12, q14 1024 vhadd.u16 q13, q13, q15 1025 vrshrn.i16 d24, q12, #8 1026 vrshrn.i16 d25, q13, #8 1027 vst1.32 {d24[0]}, [r0, :32], r1 1028 vst1.32 {d24[1]}, [r6, :32], r1 1029 subs r4, r4, #4 1030 vst1.32 {d25[0]}, [r0, :32], r1 1031 vst1.32 {d25[1]}, [r6, :32], r1 1032 bgt 4b 1033 pop {r4-r10, pc} 103480: 1035 vld1.8 {d16}, [r8] // top 1036 vld1.8 {d18}, [r10, :64] // weights_hor 1037 sub r2, r2, #2 1038 mov r7, #-2 1039 vdup.8 q3, d16[7] // right 1040 vsubl.u8 q8, d16, d4 // top-bottom 1041 vmovl.u8 q9, d18 // weights_hor 10428: 1043 vld2.8 {d0[], d1[]}, [r2, :16], r7 // left 1044 vld2.8 {d20[], d22[]}, [r12, :16]! // weights_ver 1045 vshll.i8 q12, d6, #8 // right*256 1046 vshll.i8 q13, d6, #8 1047 vshll.i8 q14, d4, #8 // bottom*256 1048 vshll.i8 q15, d4, #8 1049 vsubl.u8 q1, d0, d6 // left-right (left flipped) 1050 vsubl.u8 q0, d1, d6 1051 vmovl.u8 q10, d20 // weights_ver 1052 vmovl.u8 q11, d22 1053 vmla.i16 q12, q0, q9 // right*256 + (left-right)*weights_hor 1054 vmla.i16 q13, q1, q9 1055 vmla.i16 q14, q8, q10 // bottom*256 + (top-bottom)*weights_ver 1056 vmla.i16 q15, q8, q11 1057 vhadd.u16 q12, q12, q14 1058 vhadd.u16 q13, q13, q15 1059 vrshrn.i16 d24, q12, #8 1060 vrshrn.i16 d25, q13, #8 1061 subs r4, r4, #2 1062 vst1.8 {d24}, [r0, :64], r1 1063 vst1.8 {d25}, [r6, :64], r1 1064 bgt 8b 1065 pop {r4-r10, pc} 1066160: 1067320: 1068640: 1069 add lr, r2, r3 1070 sub r2, r2, #2 1071 mov r7, #-2 1072 vld1.8 {d6[], d7[]}, [lr] // right 1073 sub r1, r1, r3 1074 mov r9, r3 1075 10761: 1077 vld2.8 {d0[], d1[]}, [r2, :16], r7 // left 1078 vld2.8 {d20[], d22[]}, [r12, :16]! // weights_ver 1079 vsubl.u8 q1, d0, d6 // left-right (left flipped) 1080 vsubl.u8 q0, d1, d6 1081 vmovl.u8 q10, d20 // weights_ver 1082 vmovl.u8 q11, d22 10832: 1084 vld1.8 {d16}, [r8]! // top 1085 vld1.8 {d18}, [r10, :64]! // weights_hor 1086 vshll.i8 q12, d6, #8 // right*256 1087 vshll.i8 q13, d6, #8 1088 vmovl.u8 q9, d18 // weights_hor 1089 vshll.i8 q14, d4, #8 // bottom*256 1090 vshll.i8 q15, d4, #8 1091 vsubl.u8 q8, d16, d4 // top-bottom 1092 vmla.i16 q12, q0, q9 // right*256 + (left-right)*weights_hor 1093 vmla.i16 q13, q1, q9 1094 vmla.i16 q14, q8, q10 // bottom*256 + (top-bottom)*weights_ver 1095 vmla.i16 q15, q8, q11 1096 vhadd.u16 q12, q12, q14 1097 vhadd.u16 q13, q13, q15 1098 vrshrn.i16 d24, q12, #8 1099 vrshrn.i16 d25, q13, #8 1100 subs r3, r3, #8 1101 vst1.8 {d24}, [r0, :64]! 1102 vst1.8 {d25}, [r6, :64]! 1103 bgt 2b 1104 subs r4, r4, #2 1105 ble 9f 1106 sub r8, r8, r9 1107 sub r10, r10, r9 1108 add r0, r0, r1 1109 add r6, r6, r1 1110 mov r3, r9 1111 b 1b 11129: 1113 pop {r4-r10, pc} 1114endfunc 1115 1116// void ipred_smooth_v_8bpc_neon(pixel *dst, const ptrdiff_t stride, 1117// const pixel *const topleft, 1118// const int width, const int height, const int a, 1119// const int max_width, const int max_height); 1120function ipred_smooth_v_8bpc_neon, export=1 1121 push {r4-r7, lr} 1122 ldr r4, [sp, #20] 1123 movrel r7, X(sm_weights) 1124 add r7, r7, r4 1125 clz lr, r3 1126 adr r5, L(ipred_smooth_v_tbl) 1127 sub r12, r2, r4 1128 sub lr, lr, #25 1129 ldr lr, [r5, lr, lsl #2] 1130 vld1.8 {d4[]}, [r12] // bottom 1131 add r2, r2, #1 1132 add r5, r5, lr 1133 add r6, r0, r1 1134 lsl r1, r1, #1 1135 bx r5 1136 1137 .align 2 1138L(ipred_smooth_v_tbl): 1139 .word 640f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1140 .word 320f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1141 .word 160f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1142 .word 80f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1143 .word 40f - L(ipred_smooth_v_tbl) + CONFIG_THUMB 1144 114540: 1146 vld1.32 {d6[]}, [r2] // top 1147 vsubl.u8 q3, d6, d4 // top-bottom 11484: 1149 vld4.8 {d16[], d17[], d18[], d19[]}, [r7, :32]! // weights_ver 1150 vshll.i8 q10, d4, #8 // bottom*256 1151 vshll.i8 q11, d4, #8 1152 vzip.32 d16, d17 // weights_ver 1153 vzip.32 d18, d19 1154 vmovl.u8 q8, d16 // weights_ver 1155 vmovl.u8 q9, d18 1156 subs r4, r4, #4 1157 vmla.i16 q10, q3, q8 // bottom*256 + (top-bottom)*weights_ver 1158 vmla.i16 q11, q3, q9 1159 vrshrn.i16 d20, q10, #8 1160 vrshrn.i16 d21, q11, #8 1161 vst1.32 {d20[0]}, [r0, :32], r1 1162 vst1.32 {d20[1]}, [r6, :32], r1 1163 vst1.32 {d21[0]}, [r0, :32], r1 1164 vst1.32 {d21[1]}, [r6, :32], r1 1165 bgt 4b 1166 pop {r4-r7, pc} 116780: 1168 vld1.8 {d6}, [r2] // top 1169 vsubl.u8 q3, d6, d4 // top-bottom 11708: 1171 vld4.8 {d16[], d18[], d20[], d22[]}, [r7, :32]! // weights_ver 1172 vshll.i8 q12, d4, #8 // bottom*256 1173 vshll.i8 q13, d4, #8 1174 vshll.i8 q14, d4, #8 1175 vshll.i8 q15, d4, #8 1176 vmovl.u8 q8, d16 // weights_ver 1177 vmovl.u8 q9, d18 1178 vmovl.u8 q10, d20 1179 vmovl.u8 q11, d22 1180 vmla.i16 q12, q3, q8 // bottom*256 + (top-bottom)*weights_ver 1181 vmla.i16 q13, q3, q9 1182 vmla.i16 q14, q3, q10 1183 vmla.i16 q15, q3, q11 1184 vrshrn.i16 d24, q12, #8 1185 vrshrn.i16 d25, q13, #8 1186 vrshrn.i16 d26, q14, #8 1187 vrshrn.i16 d27, q15, #8 1188 vst1.8 {d24}, [r0, :64], r1 1189 vst1.8 {d25}, [r6, :64], r1 1190 subs r4, r4, #4 1191 vst1.8 {d26}, [r0, :64], r1 1192 vst1.8 {d27}, [r6, :64], r1 1193 bgt 8b 1194 pop {r4-r7, pc} 1195160: 1196320: 1197640: 1198 vpush {q4-q7} 1199 // Set up pointers for four rows in parallel; r0, r6, r5, lr 1200 add r5, r0, r1 1201 add lr, r6, r1 1202 lsl r1, r1, #1 1203 sub r1, r1, r3 1204 mov r12, r3 1205 12061: 1207 vld4.8 {d8[], d10[], d12[], d14[]}, [r7, :32]! // weights_ver 1208 vmovl.u8 q4, d8 // weights_ver 1209 vmovl.u8 q5, d10 1210 vmovl.u8 q6, d12 1211 vmovl.u8 q7, d14 12122: 1213 vld1.8 {q3}, [r2]! // top 1214 vshll.i8 q8, d4, #8 // bottom*256 1215 vshll.i8 q9, d4, #8 1216 vshll.i8 q10, d4, #8 1217 vshll.i8 q11, d4, #8 1218 vsubl.u8 q0, d6, d4 // top-bottom 1219 vsubl.u8 q1, d7, d4 1220 vshll.i8 q12, d4, #8 1221 vshll.i8 q13, d4, #8 1222 vshll.i8 q14, d4, #8 1223 vshll.i8 q15, d4, #8 1224 vmla.i16 q8, q0, q4 // bottom*256 + (top-bottom)*weights_ver 1225 vmla.i16 q9, q1, q4 1226 vmla.i16 q10, q0, q5 1227 vmla.i16 q11, q1, q5 1228 vmla.i16 q12, q0, q6 // bottom*256 + (top-bottom)*weights_ver 1229 vmla.i16 q13, q1, q6 1230 vmla.i16 q14, q0, q7 1231 vmla.i16 q15, q1, q7 1232 vrshrn.i16 d16, q8, #8 1233 vrshrn.i16 d17, q9, #8 1234 vrshrn.i16 d18, q10, #8 1235 vrshrn.i16 d19, q11, #8 1236 vrshrn.i16 d20, q12, #8 1237 vrshrn.i16 d21, q13, #8 1238 vrshrn.i16 d22, q14, #8 1239 vrshrn.i16 d23, q15, #8 1240 subs r3, r3, #16 1241 vst1.8 {q8}, [r0, :128]! 1242 vst1.8 {q9}, [r6, :128]! 1243 vst1.8 {q10}, [r5, :128]! 1244 vst1.8 {q11}, [lr, :128]! 1245 bgt 2b 1246 subs r4, r4, #4 1247 ble 9f 1248 sub r2, r2, r12 1249 add r0, r0, r1 1250 add r6, r6, r1 1251 add r5, r5, r1 1252 add lr, lr, r1 1253 mov r3, r12 1254 b 1b 12559: 1256 vpop {q4-q7} 1257 pop {r4-r7, pc} 1258endfunc 1259 1260// void ipred_smooth_h_8bpc_neon(pixel *dst, const ptrdiff_t stride, 1261// const pixel *const topleft, 1262// const int width, const int height, const int a, 1263// const int max_width, const int max_height); 1264function ipred_smooth_h_8bpc_neon, export=1 1265 push {r4-r8, lr} 1266 ldr r4, [sp, #24] 1267 movrel r8, X(sm_weights) 1268 add r8, r8, r3 1269 clz lr, r3 1270 adr r5, L(ipred_smooth_h_tbl) 1271 add r12, r2, r3 1272 sub lr, lr, #25 1273 ldr lr, [r5, lr, lsl #2] 1274 vld1.8 {d4[]}, [r12] // right 1275 add r5, r5, lr 1276 add r6, r0, r1 1277 lsl r1, r1, #1 1278 bx r5 1279 1280 .align 2 1281L(ipred_smooth_h_tbl): 1282 .word 640f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1283 .word 320f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1284 .word 160f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1285 .word 80f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1286 .word 40f - L(ipred_smooth_h_tbl) + CONFIG_THUMB 1287 128840: 1289 vld1.32 {d6[]}, [r8, :32] // weights_hor 1290 sub r2, r2, #4 1291 mov r7, #-4 1292 vmovl.u8 q3, d6 // weights_hor 12934: 1294 vld4.8 {d0[], d1[], d2[], d3[]}, [r2, :32], r7 // left 1295 vshll.i8 q8, d4, #8 // right*256 1296 vshll.i8 q9, d4, #8 1297 vzip.32 d3, d2 // left, flipped 1298 vzip.32 d1, d0 1299 vsubl.u8 q1, d3, d4 // left-right 1300 vsubl.u8 q0, d1, d4 1301 subs r4, r4, #4 1302 vmla.i16 q8, q1, q3 // right*256 + (left-right)*weights_hor 1303 vmla.i16 q9, q0, q3 1304 vrshrn.i16 d16, q8, #8 1305 vrshrn.i16 d17, q9, #8 1306 vst1.32 {d16[0]}, [r0, :32], r1 1307 vst1.32 {d16[1]}, [r6, :32], r1 1308 vst1.32 {d17[0]}, [r0, :32], r1 1309 vst1.32 {d17[1]}, [r6, :32], r1 1310 bgt 4b 1311 pop {r4-r8, pc} 131280: 1313 vld1.8 {d6}, [r8, :64] // weights_hor 1314 sub r2, r2, #4 1315 mov r7, #-4 1316 vmovl.u8 q3, d6 // weights_hor 13178: 1318 vld4.8 {d16[], d18[], d20[], d22[]}, [r2, :32], r7 // left 1319 vshll.i8 q12, d4, #8 // right*256 1320 vshll.i8 q13, d4, #8 1321 vshll.i8 q14, d4, #8 1322 vshll.i8 q15, d4, #8 1323 vsubl.u8 q11, d22, d4 // left-right 1324 vsubl.u8 q10, d20, d4 1325 vsubl.u8 q9, d18, d4 1326 vsubl.u8 q8, d16, d4 1327 vmla.i16 q12, q11, q3 // right*256 + (left-right)*weights_hor 1328 vmla.i16 q13, q10, q3 // (left flipped) 1329 vmla.i16 q14, q9, q3 1330 vmla.i16 q15, q8, q3 1331 vrshrn.i16 d24, q12, #8 1332 vrshrn.i16 d25, q13, #8 1333 vrshrn.i16 d26, q14, #8 1334 vrshrn.i16 d27, q15, #8 1335 vst1.8 {d24}, [r0, :64], r1 1336 vst1.8 {d25}, [r6, :64], r1 1337 subs r4, r4, #4 1338 vst1.8 {d26}, [r0, :64], r1 1339 vst1.8 {d27}, [r6, :64], r1 1340 bgt 8b 1341 pop {r4-r8, pc} 1342160: 1343320: 1344640: 1345 vpush {q4-q7} 1346 sub r2, r2, #4 1347 mov r7, #-4 1348 // Set up pointers for four rows in parallel; r0, r6, r5, lr 1349 add r5, r0, r1 1350 add lr, r6, r1 1351 lsl r1, r1, #1 1352 sub r1, r1, r3 1353 mov r12, r3 1354 13551: 1356 vld4.8 {d8[], d10[], d12[], d14[]}, [r2, :32], r7 // left 1357 vsubl.u8 q4, d8, d4 // left-right 1358 vsubl.u8 q5, d10, d4 1359 vsubl.u8 q6, d12, d4 1360 vsubl.u8 q7, d14, d4 13612: 1362 vld1.8 {q1}, [r8, :128]! // weights_hor 1363 vshll.i8 q8, d4, #8 // right*256 1364 vshll.i8 q9, d4, #8 1365 vshll.i8 q10, d4, #8 1366 vshll.i8 q11, d4, #8 1367 vmovl.u8 q0, d2 // weights_hor 1368 vmovl.u8 q1, d3 1369 vshll.i8 q12, d4, #8 1370 vshll.i8 q13, d4, #8 1371 vshll.i8 q14, d4, #8 1372 vshll.i8 q15, d4, #8 1373 vmla.i16 q8, q7, q0 // right*256 + (left-right)*weights_hor 1374 vmla.i16 q9, q7, q1 // (left flipped) 1375 vmla.i16 q10, q6, q0 1376 vmla.i16 q11, q6, q1 1377 vmla.i16 q12, q5, q0 1378 vmla.i16 q13, q5, q1 1379 vmla.i16 q14, q4, q0 1380 vmla.i16 q15, q4, q1 1381 vrshrn.i16 d16, q8, #8 1382 vrshrn.i16 d17, q9, #8 1383 vrshrn.i16 d18, q10, #8 1384 vrshrn.i16 d19, q11, #8 1385 vrshrn.i16 d20, q12, #8 1386 vrshrn.i16 d21, q13, #8 1387 vrshrn.i16 d22, q14, #8 1388 vrshrn.i16 d23, q15, #8 1389 subs r3, r3, #16 1390 vst1.8 {q8}, [r0, :128]! 1391 vst1.8 {q9}, [r6, :128]! 1392 vst1.8 {q10}, [r5, :128]! 1393 vst1.8 {q11}, [lr, :128]! 1394 bgt 2b 1395 subs r4, r4, #4 1396 ble 9f 1397 sub r8, r8, r12 1398 add r0, r0, r1 1399 add r6, r6, r1 1400 add r5, r5, r1 1401 add lr, lr, r1 1402 mov r3, r12 1403 b 1b 14049: 1405 vpop {q4-q7} 1406 pop {r4-r8, pc} 1407endfunc 1408 1409// void ipred_filter_8bpc_neon(pixel *dst, const ptrdiff_t stride, 1410// const pixel *const topleft, 1411// const int width, const int height, const int filt_idx, 1412// const int max_width, const int max_height); 1413function ipred_filter_8bpc_neon, export=1 1414 push {r4-r8, lr} 1415 movw r12, #511 1416 ldrd r4, r5, [sp, #24] 1417 and r5, r5, r12 // 511 1418 movrel r6, X(filter_intra_taps) 1419 lsl r5, r5, #6 1420 add r6, r6, r5 1421 vld1.8 {d20, d21, d22, d23}, [r6, :128]! 1422 clz lr, r3 1423 adr r5, L(ipred_filter_tbl) 1424 vld1.8 {d27, d28, d29}, [r6, :64] 1425 sub lr, lr, #26 1426 ldr lr, [r5, lr, lsl #2] 1427 vmovl.s8 q8, d20 1428 vmovl.s8 q9, d21 1429 add r5, r5, lr 1430 vmovl.s8 q10, d22 1431 vmovl.s8 q11, d23 1432 add r6, r0, r1 1433 lsl r1, r1, #1 1434 vmovl.s8 q12, d27 1435 vmovl.s8 q13, d28 1436 vmovl.s8 q14, d29 1437 add r8, r2, #1 1438 sub r2, r2, #2 1439 mov r7, #-2 1440 bx r5 1441 1442 .align 2 1443L(ipred_filter_tbl): 1444 .word 320f - L(ipred_filter_tbl) + CONFIG_THUMB 1445 .word 160f - L(ipred_filter_tbl) + CONFIG_THUMB 1446 .word 80f - L(ipred_filter_tbl) + CONFIG_THUMB 1447 .word 40f - L(ipred_filter_tbl) + CONFIG_THUMB 1448 144940: 1450 vld1.32 {d0[]}, [r8] // top (0-3) 1451 vmovl.u8 q0, d0 // top (0-3) 14524: 1453 vld1.32 {d2[]}, [r2], r7 // left (0-1) + topleft (2) 1454 vmul.i16 q2, q9, d0[0] // p1(top[0]) * filter(1) 1455 vmla.i16 q2, q10, d0[1] // p2(top[1]) * filter(2) 1456 vmla.i16 q2, q11, d0[2] // p3(top[2]) * filter(3) 1457 vmovl.u8 q1, d2 // left (0-1) + topleft (2) 1458 vmla.i16 q2, q12, d0[3] // p4(top[3]) * filter(4) 1459 vmla.i16 q2, q8, d2[2] // p0(topleft) * filter(0) 1460 vmla.i16 q2, q13, d2[1] // p5(left[0]) * filter(5) 1461 vmla.i16 q2, q14, d2[0] // p6(left[1]) * filter(6) 1462 vqrshrun.s16 d4, q2, #4 1463 subs r4, r4, #2 1464 vst1.32 {d4[0]}, [r0, :32], r1 1465 vmovl.u8 q0, d4 1466 vst1.32 {d4[1]}, [r6, :32], r1 1467 vmov d0, d1 // move top from [4-7] to [0-3] 1468 bgt 4b 1469 pop {r4-r8, pc} 147080: 1471 vld1.8 {d0}, [r8] // top (0-7) 1472 vmovl.u8 q0, d0 // top (0-7) 14738: 1474 vld1.32 {d2[]}, [r2], r7 // left (0-1) + topleft (2) 1475 vmul.i16 q2, q9, d0[0] // p1(top[0]) * filter(1) 1476 vmla.i16 q2, q10, d0[1] // p2(top[1]) * filter(2) 1477 vmla.i16 q2, q11, d0[2] // p3(top[2]) * filter(3) 1478 vmovl.u8 q1, d2 // left (0-1) + topleft (2) 1479 vmla.i16 q2, q12, d0[3] // p4(top[3]) * filter(4) 1480 vmla.i16 q2, q8, d2[2] // p0(topleft) * filter(0) 1481 vmla.i16 q2, q13, d2[1] // p5(left[0]) * filter(5) 1482 vmla.i16 q2, q14, d2[0] // p6(left[1]) * filter(6) 1483 vmul.i16 q3, q9, d1[0] // p1(top[0]) * filter(1) 1484 vmla.i16 q3, q10, d1[1] // p2(top[1]) * filter(2) 1485 vmla.i16 q3, q11, d1[2] // p3(top[2]) * filter(3) 1486 vqrshrun.s16 d4, q2, #4 1487 vmovl.u8 q1, d4 // first block, in 16 bit 1488 vmla.i16 q3, q12, d1[3] // p4(top[3]) * filter(4) 1489 vmla.i16 q3, q8, d0[3] // p0(topleft) * filter(0) 1490 vmla.i16 q3, q13, d2[3] // p5(left[0]) * filter(5) 1491 vmla.i16 q3, q14, d3[3] // p6(left[1]) * filter(6) 1492 vqrshrun.s16 d5, q3, #4 1493 vzip.32 d4, d5 1494 subs r4, r4, #2 1495 vst1.8 {d4}, [r0, :64], r1 1496 vmovl.u8 q0, d5 1497 vst1.8 {d5}, [r6, :64], r1 1498 bgt 8b 1499 pop {r4-r8, pc} 1500160: 1501320: 1502 vpush {q4-q5} 1503 sub r1, r1, r3 1504 mov lr, r3 1505 15061: 1507 vld1.32 {d0[]}, [r2], r7 // left (0-1) + topleft (2) 1508 vmovl.u8 q0, d0 // left (0-1) + topleft (2) 15092: 1510 vld1.8 {q2}, [r8]! // top(0-15) 1511 vmul.i16 q3, q8, d0[2] // p0(topleft) * filter(0) 1512 vmla.i16 q3, q13, d0[1] // p5(left[0]) * filter(5) 1513 vmovl.u8 q1, d4 // top(0-7) 1514 vmovl.u8 q2, d5 // top(8-15) 1515 vmla.i16 q3, q14, d0[0] // p6(left[1]) * filter(6) 1516 vmla.i16 q3, q9, d2[0] // p1(top[0]) * filter(1) 1517 vmla.i16 q3, q10, d2[1] // p2(top[1]) * filter(2) 1518 vmla.i16 q3, q11, d2[2] // p3(top[2]) * filter(3) 1519 vmla.i16 q3, q12, d2[3] // p4(top[3]) * filter(4) 1520 1521 vmul.i16 q4, q9, d3[0] // p1(top[0]) * filter(1) 1522 vmla.i16 q4, q10, d3[1] // p2(top[1]) * filter(2) 1523 vmla.i16 q4, q11, d3[2] // p3(top[2]) * filter(3) 1524 vqrshrun.s16 d6, q3, #4 1525 vmovl.u8 q0, d6 // first block, in 16 bit 1526 vmla.i16 q4, q12, d3[3] // p4(top[3]) * filter(4) 1527 vmla.i16 q4, q8, d2[3] // p0(topleft) * filter(0) 1528 vmla.i16 q4, q13, d0[3] // p5(left[0]) * filter(5) 1529 vmla.i16 q4, q14, d1[3] // p6(left[1]) * filter(6) 1530 1531 vmul.i16 q5, q9, d4[0] // p1(top[0]) * filter(1) 1532 vmla.i16 q5, q10, d4[1] // p2(top[1]) * filter(2) 1533 vmla.i16 q5, q11, d4[2] // p3(top[2]) * filter(3) 1534 vqrshrun.s16 d7, q4, #4 1535 vmovl.u8 q0, d7 // second block, in 16 bit 1536 vmla.i16 q5, q12, d4[3] // p4(top[3]) * filter(4) 1537 vmla.i16 q5, q8, d3[3] // p0(topleft) * filter(0) 1538 vmla.i16 q5, q13, d0[3] // p5(left[0]) * filter(5) 1539 vmla.i16 q5, q14, d1[3] // p6(left[1]) * filter(6) 1540 1541 vmul.i16 q15, q9, d5[0] // p1(top[0]) * filter(1) 1542 vmla.i16 q15, q10, d5[1] // p2(top[1]) * filter(2) 1543 vmla.i16 q15, q11, d5[2] // p3(top[2]) * filter(3) 1544 vqrshrun.s16 d8, q5, #4 1545 vmovl.u8 q0, d8 // third block, in 16 bit 1546 vmov.u8 r12, d5[6] 1547 vmla.i16 q15, q12, d5[3] // p4(top[3]) * filter(4) 1548 vmla.i16 q15, q8, d4[3] // p0(topleft) * filter(0) 1549 vmla.i16 q15, q13, d0[3] // p5(left[0]) * filter(5) 1550 vmla.i16 q15, q14, d1[3] // p6(left[1]) * filter(6) 1551 vmov.8 d0[4], r12 1552 1553 subs r3, r3, #16 1554 vqrshrun.s16 d9, q15, #4 1555 1556 vst4.32 {d6[0], d7[0], d8[0], d9[0]}, [r0, :128]! 1557 vst4.32 {d6[1], d7[1], d8[1], d9[1]}, [r6, :128]! 1558 ble 8f 1559 vmov.u8 r12, d9[7] 1560 vmov.8 d0[0], r12 1561 vmov.u8 r12, d9[3] 1562 vmov.8 d0[2], r12 1563 b 2b 15648: 1565 subs r4, r4, #2 1566 1567 ble 9f 1568 sub r8, r6, lr 1569 add r0, r0, r1 1570 add r6, r6, r1 1571 mov r3, lr 1572 b 1b 15739: 1574 vpop {q4-q5} 1575 pop {r4-r8, pc} 1576endfunc 1577 1578// void pal_pred_8bpc_neon(pixel *dst, const ptrdiff_t stride, 1579// const pixel *const pal, const uint8_t *idx, 1580// const int w, const int h); 1581function pal_pred_8bpc_neon, export=1 1582 push {r4-r5, lr} 1583 ldrd r4, r5, [sp, #12] 1584 vld1.8 {d0}, [r2, :64] 1585 clz lr, r4 1586 adr r12, L(pal_pred_tbl) 1587 sub lr, lr, #25 1588 vmov.i8 q15, #7 1589 ldr lr, [r12, lr, lsl #2] 1590 add r12, r12, lr 1591 add r2, r0, r1 1592 bx r12 1593 1594 .align 2 1595L(pal_pred_tbl): 1596 .word 640f - L(pal_pred_tbl) + CONFIG_THUMB 1597 .word 320f - L(pal_pred_tbl) + CONFIG_THUMB 1598 .word 160f - L(pal_pred_tbl) + CONFIG_THUMB 1599 .word 80f - L(pal_pred_tbl) + CONFIG_THUMB 1600 .word 40f - L(pal_pred_tbl) + CONFIG_THUMB 1601 160240: 1603 lsl r1, r1, #1 16044: 1605 vld1.8 {d2}, [r3, :64]! 1606 subs r5, r5, #4 1607 vshr.u8 d3, d2, #4 1608 vand.u8 d2, d2, d30 1609 vzip.8 d2, d3 1610 vtbl.8 d2, {d0}, d2 1611 vtbl.8 d3, {d0}, d3 1612 vst1.32 {d2[0]}, [r0, :32], r1 1613 vst1.32 {d2[1]}, [r2, :32], r1 1614 vst1.32 {d3[0]}, [r0, :32], r1 1615 vst1.32 {d3[1]}, [r2, :32], r1 1616 bgt 4b 1617 pop {r4-r5, pc} 161880: 1619 lsl r1, r1, #1 16208: 1621 vld1.8 {q1}, [r3, :64]! 1622 subs r5, r5, #4 1623 vshr.u8 q2, q1, #4 1624 vand.u8 q1, q1, q15 1625 vzip.8 q1, q2 1626 vtbl.8 d2, {d0}, d2 1627 vtbl.8 d3, {d0}, d3 1628 vst1.8 {d2}, [r0, :64], r1 1629 vtbl.8 d4, {d0}, d4 1630 vst1.8 {d3}, [r2, :64], r1 1631 vtbl.8 d5, {d0}, d5 1632 vst1.8 {d4}, [r0, :64], r1 1633 vst1.8 {d5}, [r2, :64], r1 1634 bgt 8b 1635 pop {r4-r5, pc} 1636160: 1637 lsl r1, r1, #1 163816: 1639 vld1.8 {q10, q11}, [r3, :64]! 1640 subs r5, r5, #4 1641 vand.u8 q8, q10, q15 1642 vshr.u8 q9, q10, #4 1643 vand.u8 q10, q11, q15 1644 vshr.u8 q11, q11, #4 1645 vzip.8 q8, q9 1646 vzip.8 q10, q11 1647 vtbl.8 d16, {d0}, d16 1648 vtbl.8 d17, {d0}, d17 1649 vtbl.8 d18, {d0}, d18 1650 vtbl.8 d19, {d0}, d19 1651 vtbl.8 d20, {d0}, d20 1652 vtbl.8 d21, {d0}, d21 1653 vst1.8 {q8}, [r0, :128], r1 1654 vtbl.8 d22, {d0}, d22 1655 vst1.8 {q9}, [r2, :128], r1 1656 vtbl.8 d23, {d0}, d23 1657 vst1.8 {q10}, [r0, :128], r1 1658 vst1.8 {q11}, [r2, :128], r1 1659 bgt 16b 1660 pop {r4-r5, pc} 1661320: 1662 lsl r1, r1, #1 166332: 1664 vld1.8 {q10, q11}, [r3, :64]! 1665 subs r5, r5, #2 1666 vand.u8 q8, q10, q15 1667 vshr.u8 q9, q10, #4 1668 vand.u8 q10, q11, q15 1669 vshr.u8 q11, q11, #4 1670 vzip.8 q8, q9 1671 vzip.8 q10, q11 1672 vtbl.8 d16, {d0}, d16 1673 vtbl.8 d17, {d0}, d17 1674 vtbl.8 d18, {d0}, d18 1675 vtbl.8 d19, {d0}, d19 1676 vtbl.8 d20, {d0}, d20 1677 vtbl.8 d21, {d0}, d21 1678 vst1.8 {q8, q9}, [r0, :128], r1 1679 vtbl.8 d22, {d0}, d22 1680 vtbl.8 d23, {d0}, d23 1681 vst1.8 {q10, q11}, [r2, :128], r1 1682 bgt 32b 1683 pop {r4-r5, pc} 1684640: 1685 sub r1, r1, #32 168664: 1687 vld1.8 {q10, q11}, [r3, :64]! 1688 subs r5, r5, #1 1689 vand.u8 q8, q10, q15 1690 vshr.u8 q9, q10, #4 1691 vand.u8 q10, q11, q15 1692 vshr.u8 q11, q11, #4 1693 vzip.8 q8, q9 1694 vzip.8 q10, q11 1695 vtbl.8 d16, {d0}, d16 1696 vtbl.8 d17, {d0}, d17 1697 vtbl.8 d18, {d0}, d18 1698 vtbl.8 d19, {d0}, d19 1699 vtbl.8 d20, {d0}, d20 1700 vtbl.8 d21, {d0}, d21 1701 vst1.8 {q8, q9}, [r0, :128]! 1702 vtbl.8 d22, {d0}, d22 1703 vtbl.8 d23, {d0}, d23 1704 vst1.8 {q10, q11}, [r0, :128], r1 1705 bgt 64b 1706 pop {r4-r5, pc} 1707endfunc 1708 1709// void ipred_cfl_128_8bpc_neon(pixel *dst, const ptrdiff_t stride, 1710// const pixel *const topleft, 1711// const int width, const int height, 1712// const int16_t *ac, const int alpha); 1713function ipred_cfl_128_8bpc_neon, export=1 1714 push {r4-r8, lr} 1715 ldrd r4, r5, [sp, #24] 1716 ldr r6, [sp, #32] 1717 clz lr, r3 1718 adr r12, L(ipred_cfl_128_tbl) 1719 sub lr, lr, #26 1720 ldr lr, [r12, lr, lsl #2] 1721 vmov.i16 q0, #128 // dc 1722 vdup.i16 q1, r6 // alpha 1723 add r12, r12, lr 1724 add r6, r0, r1 1725 lsl r1, r1, #1 1726 bx r12 1727 1728 .align 2 1729L(ipred_cfl_128_tbl): 1730L(ipred_cfl_splat_tbl): 1731 .word L(ipred_cfl_splat_w16) - L(ipred_cfl_128_tbl) + CONFIG_THUMB 1732 .word L(ipred_cfl_splat_w16) - L(ipred_cfl_128_tbl) + CONFIG_THUMB 1733 .word L(ipred_cfl_splat_w8) - L(ipred_cfl_128_tbl) + CONFIG_THUMB 1734 .word L(ipred_cfl_splat_w4) - L(ipred_cfl_128_tbl) + CONFIG_THUMB 1735 1736L(ipred_cfl_splat_w4): 1737 vld1.16 {q2, q3}, [r5, :128]! 1738 vmul.i16 q2, q2, q1 // diff = ac * alpha 1739 vmul.i16 q3, q3, q1 1740 vshr.s16 q8, q2, #15 // sign = diff >> 15 1741 vshr.s16 q9, q3, #15 1742 vadd.i16 q2, q2, q8 // diff + sign 1743 vadd.i16 q3, q3, q9 1744 vrshr.s16 q2, q2, #6 // (diff + sign + 32) >> 6 = apply_sign() 1745 vrshr.s16 q3, q3, #6 1746 vadd.i16 q2, q2, q0 // dc + apply_sign() 1747 vadd.i16 q3, q3, q0 1748 vqmovun.s16 d4, q2 // iclip_pixel(dc + apply_sign()) 1749 vqmovun.s16 d5, q3 1750 vst1.32 {d4[0]}, [r0, :32], r1 1751 vst1.32 {d4[1]}, [r6, :32], r1 1752 subs r4, r4, #4 1753 vst1.32 {d5[0]}, [r0, :32], r1 1754 vst1.32 {d5[1]}, [r6, :32], r1 1755 bgt L(ipred_cfl_splat_w4) 1756 pop {r4-r8, pc} 1757L(ipred_cfl_splat_w8): 1758 vld1.16 {q8, q9}, [r5, :128]! 1759 vld1.16 {q10, q11}, [r5, :128]! 1760 vmul.i16 q8, q8, q1 // diff = ac * alpha 1761 vmul.i16 q9, q9, q1 1762 vmul.i16 q10, q10, q1 1763 vmul.i16 q11, q11, q1 1764 vshr.s16 q12, q8, #15 // sign = diff >> 15 1765 vshr.s16 q13, q9, #15 1766 vshr.s16 q14, q10, #15 1767 vshr.s16 q15, q11, #15 1768 vadd.i16 q8, q8, q12 // diff + sign 1769 vadd.i16 q9, q9, q13 1770 vadd.i16 q10, q10, q14 1771 vadd.i16 q11, q11, q15 1772 vrshr.s16 q8, q8, #6 // (diff + sign + 32) >> 6 = apply_sign() 1773 vrshr.s16 q9, q9, #6 1774 vrshr.s16 q10, q10, #6 1775 vrshr.s16 q11, q11, #6 1776 vadd.i16 q8, q8, q0 // dc + apply_sign() 1777 vadd.i16 q9, q9, q0 1778 vadd.i16 q10, q10, q0 1779 vadd.i16 q11, q11, q0 1780 vqmovun.s16 d16, q8 // iclip_pixel(dc + apply_sign()) 1781 vqmovun.s16 d17, q9 1782 vqmovun.s16 d18, q10 1783 vqmovun.s16 d19, q11 1784 vst1.8 {d16}, [r0, :64], r1 1785 vst1.8 {d17}, [r6, :64], r1 1786 subs r4, r4, #4 1787 vst1.8 {d18}, [r0, :64], r1 1788 vst1.8 {d19}, [r6, :64], r1 1789 bgt L(ipred_cfl_splat_w8) 1790 pop {r4-r8, pc} 1791L(ipred_cfl_splat_w16): 1792 add r12, r5, r3, lsl #1 1793 sub r1, r1, r3 1794 mov lr, r3 17951: 1796 vld1.16 {q8, q9}, [r5, :128]! 1797 vmul.i16 q8, q8, q1 // diff = ac * alpha 1798 vld1.16 {q10, q11}, [r12, :128]! 1799 vmul.i16 q9, q9, q1 1800 vmul.i16 q10, q10, q1 1801 vmul.i16 q11, q11, q1 1802 vshr.s16 q12, q8, #15 // sign = diff >> 15 1803 vshr.s16 q13, q9, #15 1804 vshr.s16 q14, q10, #15 1805 vshr.s16 q15, q11, #15 1806 vadd.i16 q8, q8, q12 // diff + sign 1807 vadd.i16 q9, q9, q13 1808 vadd.i16 q10, q10, q14 1809 vadd.i16 q11, q11, q15 1810 vrshr.s16 q8, q8, #6 // (diff + sign + 32) >> 6 = apply_sign() 1811 vrshr.s16 q9, q9, #6 1812 vrshr.s16 q10, q10, #6 1813 vrshr.s16 q11, q11, #6 1814 vadd.i16 q8, q8, q0 // dc + apply_sign() 1815 vadd.i16 q9, q9, q0 1816 vadd.i16 q10, q10, q0 1817 vadd.i16 q11, q11, q0 1818 vqmovun.s16 d16, q8 // iclip_pixel(dc + apply_sign()) 1819 vqmovun.s16 d17, q9 1820 vqmovun.s16 d18, q10 1821 vqmovun.s16 d19, q11 1822 subs r3, r3, #16 1823 vst1.16 {q8}, [r0, :128]! 1824 vst1.16 {q9}, [r6, :128]! 1825 bgt 1b 1826 subs r4, r4, #2 1827 add r5, r5, lr, lsl #1 1828 add r12, r12, lr, lsl #1 1829 add r0, r0, r1 1830 add r6, r6, r1 1831 mov r3, lr 1832 bgt 1b 1833 pop {r4-r8, pc} 1834endfunc 1835 1836// void ipred_cfl_top_8bpc_neon(pixel *dst, const ptrdiff_t stride, 1837// const pixel *const topleft, 1838// const int width, const int height, 1839// const int16_t *ac, const int alpha); 1840function ipred_cfl_top_8bpc_neon, export=1 1841 push {r4-r8, lr} 1842 ldrd r4, r5, [sp, #24] 1843 ldr r6, [sp, #32] 1844 clz lr, r3 1845 adr r12, L(ipred_cfl_top_tbl) 1846 sub lr, lr, #26 1847 ldr lr, [r12, lr, lsl #2] 1848 vdup.16 q1, r6 // alpha 1849 add r2, r2, #1 1850 add r12, r12, lr 1851 add r6, r0, r1 1852 lsl r1, r1, #1 1853 bx r12 1854 1855 .align 2 1856L(ipred_cfl_top_tbl): 1857 .word 32f - L(ipred_cfl_top_tbl) + CONFIG_THUMB 1858 .word 16f - L(ipred_cfl_top_tbl) + CONFIG_THUMB 1859 .word 8f - L(ipred_cfl_top_tbl) + CONFIG_THUMB 1860 .word 4f - L(ipred_cfl_top_tbl) + CONFIG_THUMB 1861 18624: 1863 vld1.32 {d0[]}, [r2] 1864 vpaddl.u8 d0, d0 1865 vpadd.u16 d0, d0 1866 vrshr.u16 d0, d0, #2 1867 vdup.16 q0, d0[0] 1868 b L(ipred_cfl_splat_w4) 18698: 1870 vld1.8 {d0}, [r2] 1871 vpaddl.u8 d0, d0 1872 vpadd.u16 d0, d0 1873 vpadd.u16 d0, d0 1874 vrshr.u16 d0, d0, #3 1875 vdup.16 q0, d0[0] 1876 b L(ipred_cfl_splat_w8) 187716: 1878 vld1.8 {q0}, [r2] 1879 vaddl.u8 q0, d0, d1 1880 vadd.u16 d0, d0, d1 1881 vpadd.u16 d0, d0 1882 vpadd.u16 d0, d0 1883 vrshr.u16 d0, d0, #4 1884 vdup.16 q0, d0[0] 1885 b L(ipred_cfl_splat_w16) 188632: 1887 vld1.8 {q2, q3}, [r2] 1888 vaddl.u8 q2, d4, d5 1889 vaddl.u8 q3, d6, d7 1890 vadd.u16 q0, q2, q3 1891 vadd.u16 d0, d0, d1 1892 vpadd.u16 d0, d0 1893 vpadd.u16 d0, d0 1894 vrshr.u16 d0, d0, #5 1895 vdup.16 q0, d0[0] 1896 b L(ipred_cfl_splat_w16) 1897endfunc 1898 1899// void ipred_cfl_left_8bpc_neon(pixel *dst, const ptrdiff_t stride, 1900// const pixel *const topleft, 1901// const int width, const int height, 1902// const int16_t *ac, const int alpha); 1903function ipred_cfl_left_8bpc_neon, export=1 1904 push {r4-r8, lr} 1905 ldrd r4, r5, [sp, #24] 1906 ldr r6, [sp, #32] 1907 sub r2, r2, r4 1908 clz lr, r3 1909 clz r8, r4 1910 adr r12, L(ipred_cfl_splat_tbl) 1911 adr r7, L(ipred_cfl_left_tbl) 1912 sub lr, lr, #26 1913 sub r8, r8, #26 1914 ldr lr, [r12, lr, lsl #2] 1915 ldr r8, [r7, r8, lsl #2] 1916 vdup.16 q1, r6 // alpha 1917 add r12, r12, lr 1918 add r7, r7, r8 1919 add r6, r0, r1 1920 lsl r1, r1, #1 1921 bx r7 1922 1923 .align 2 1924L(ipred_cfl_left_tbl): 1925 .word L(ipred_cfl_left_h32) - L(ipred_cfl_left_tbl) + CONFIG_THUMB 1926 .word L(ipred_cfl_left_h16) - L(ipred_cfl_left_tbl) + CONFIG_THUMB 1927 .word L(ipred_cfl_left_h8) - L(ipred_cfl_left_tbl) + CONFIG_THUMB 1928 .word L(ipred_cfl_left_h4) - L(ipred_cfl_left_tbl) + CONFIG_THUMB 1929 1930L(ipred_cfl_left_h4): 1931 vld1.32 {d0[]}, [r2, :32] 1932 vpaddl.u8 d0, d0 1933 vpadd.u16 d0, d0 1934 vrshr.u16 d0, d0, #2 1935 vdup.16 q0, d0[0] 1936 bx r12 1937 1938L(ipred_cfl_left_h8): 1939 vld1.8 {d0}, [r2, :64] 1940 vpaddl.u8 d0, d0 1941 vpadd.u16 d0, d0 1942 vpadd.u16 d0, d0 1943 vrshr.u16 d0, d0, #3 1944 vdup.16 q0, d0[0] 1945 bx r12 1946 1947L(ipred_cfl_left_h16): 1948 vld1.8 {q0}, [r2, :128] 1949 vaddl.u8 q0, d0, d1 1950 vadd.u16 d0, d0, d1 1951 vpadd.u16 d0, d0 1952 vpadd.u16 d0, d0 1953 vrshr.u16 d0, d0, #4 1954 vdup.16 q0, d0[0] 1955 bx r12 1956 1957L(ipred_cfl_left_h32): 1958 vld1.8 {q2, q3}, [r2, :128] 1959 vaddl.u8 q2, d4, d5 1960 vaddl.u8 q3, d6, d7 1961 vadd.u16 q0, q2, q3 1962 vadd.u16 d0, d0, d1 1963 vpadd.u16 d0, d0 1964 vpadd.u16 d0, d0 1965 vrshr.u16 d0, d0, #5 1966 vdup.16 q0, d0[0] 1967 bx r12 1968endfunc 1969 1970// void ipred_cfl_8bpc_neon(pixel *dst, const ptrdiff_t stride, 1971// const pixel *const topleft, 1972// const int width, const int height, 1973// const int16_t *ac, const int alpha); 1974function ipred_cfl_8bpc_neon, export=1 1975 push {r4-r8, lr} 1976 ldrd r4, r5, [sp, #24] 1977 ldr r6, [sp, #32] 1978 sub r2, r2, r4 1979 add r8, r3, r4 // width + height 1980 vdup.16 q1, r6 // alpha 1981 clz lr, r3 1982 clz r6, r4 1983 vdup.16 d16, r8 // width + height 1984 adr r7, L(ipred_cfl_tbl) 1985 rbit r8, r8 // rbit(width + height) 1986 sub lr, lr, #22 // 26 leading bits, minus table offset 4 1987 sub r6, r6, #26 1988 clz r8, r8 // ctz(width + height) 1989 ldr lr, [r7, lr, lsl #2] 1990 ldr r6, [r7, r6, lsl #2] 1991 neg r8, r8 // -ctz(width + height) 1992 add r12, r7, lr 1993 add r7, r7, r6 1994 vshr.u16 d16, d16, #1 // (width + height) >> 1 1995 vdup.16 d17, r8 // -ctz(width + height) 1996 add r6, r0, r1 1997 lsl r1, r1, #1 1998 bx r7 1999 2000 .align 2 2001L(ipred_cfl_tbl): 2002 .word L(ipred_cfl_h32) - L(ipred_cfl_tbl) + CONFIG_THUMB 2003 .word L(ipred_cfl_h16) - L(ipred_cfl_tbl) + CONFIG_THUMB 2004 .word L(ipred_cfl_h8) - L(ipred_cfl_tbl) + CONFIG_THUMB 2005 .word L(ipred_cfl_h4) - L(ipred_cfl_tbl) + CONFIG_THUMB 2006 .word L(ipred_cfl_w32) - L(ipred_cfl_tbl) + CONFIG_THUMB 2007 .word L(ipred_cfl_w16) - L(ipred_cfl_tbl) + CONFIG_THUMB 2008 .word L(ipred_cfl_w8) - L(ipred_cfl_tbl) + CONFIG_THUMB 2009 .word L(ipred_cfl_w4) - L(ipred_cfl_tbl) + CONFIG_THUMB 2010 2011L(ipred_cfl_h4): 2012 vld1.32 {d0[]}, [r2, :32]! 2013 vpaddl.u8 d0, d0 2014 add r2, r2, #1 2015 vpadd.i16 d0, d0 2016 bx r12 2017L(ipred_cfl_w4): 2018 vld1.32 {d1[]}, [r2] 2019 vadd.i16 d0, d0, d16 2020 vpaddl.u8 d1, d1 2021 vpadd.u16 d1, d1 2022 cmp r4, #4 2023 vadd.i16 d0, d0, d1 2024 vshl.u16 d0, d0, d17 2025 beq 1f 2026 // h = 8/16 2027 movw lr, #(0x3334/2) 2028 movw r8, #(0x5556/2) 2029 cmp r4, #16 2030 it ne 2031 movne lr, r8 2032 vdup.16 d18, lr 2033 vqdmulh.s16 d0, d0, d18 20341: 2035 vdup.16 q0, d0[0] 2036 b L(ipred_cfl_splat_w4) 2037 2038L(ipred_cfl_h8): 2039 vld1.8 {d0}, [r2, :64]! 2040 vpaddl.u8 d0, d0 2041 vpadd.i16 d0, d0 2042 add r2, r2, #1 2043 vpadd.i16 d0, d0 2044 bx r12 2045L(ipred_cfl_w8): 2046 vld1.8 {d1}, [r2] 2047 vadd.i16 d0, d0, d16 2048 vpaddl.u8 d1, d1 2049 vpadd.i16 d1, d1 2050 vpadd.i16 d1, d1 2051 cmp r4, #8 2052 vadd.i16 d0, d0, d1 2053 vshl.u16 d0, d0, d17 2054 beq 1f 2055 // h = 4/16/32 2056 cmp r4, #32 2057 movw lr, #(0x3334/2) 2058 movw r8, #(0x5556/2) 2059 it ne 2060 movne lr, r8 2061 vdup.16 d18, lr 2062 vqdmulh.s16 d0, d0, d18 20631: 2064 vdup.16 q0, d0[0] 2065 b L(ipred_cfl_splat_w8) 2066 2067L(ipred_cfl_h16): 2068 vld1.8 {q0}, [r2, :128]! 2069 vaddl.u8 q0, d0, d1 2070 vadd.i16 d0, d0, d1 2071 vpadd.i16 d0, d0 2072 add r2, r2, #1 2073 vpadd.i16 d0, d0 2074 bx r12 2075L(ipred_cfl_w16): 2076 vld1.8 {q2}, [r2] 2077 vadd.i16 d0, d0, d16 2078 vaddl.u8 q2, d4, d5 2079 vadd.i16 d4, d4, d5 2080 vpadd.i16 d4, d4 2081 vpadd.i16 d4, d4 2082 cmp r4, #16 2083 vadd.i16 d0, d0, d4 2084 vshl.u16 d0, d0, d17 2085 beq 1f 2086 // h = 4/8/32/64 2087 tst r4, #(32+16+8) // 16 added to make a consecutive bitmask 2088 movw lr, #(0x3334/2) 2089 movw r8, #(0x5556/2) 2090 it ne 2091 movne lr, r8 2092 vdup.16 d18, lr 2093 vqdmulh.s16 d0, d0, d18 20941: 2095 vdup.16 q0, d0[0] 2096 b L(ipred_cfl_splat_w16) 2097 2098L(ipred_cfl_h32): 2099 vld1.8 {q2, q3}, [r2, :128]! 2100 vaddl.u8 q2, d4, d5 2101 vaddl.u8 q3, d6, d7 2102 vadd.i16 q0, q2, q3 2103 vadd.i16 d0, d0, d1 2104 vpadd.i16 d0, d0 2105 add r2, r2, #1 2106 vpadd.i16 d0, d0 2107 bx r12 2108L(ipred_cfl_w32): 2109 vld1.8 {q2, q3}, [r2] 2110 vadd.i16 d0, d0, d16 2111 vaddl.u8 q2, d4, d5 2112 vaddl.u8 q3, d6, d7 2113 vadd.i16 q2, q2, q3 2114 vadd.i16 d4, d4, d5 2115 vpadd.i16 d4, d4 2116 vpadd.i16 d4, d4 2117 cmp r4, #32 2118 vadd.i16 d0, d0, d4 2119 vshl.u16 d0, d0, d17 2120 beq 1f 2121 // h = 8/16/64 2122 cmp r4, #8 2123 movw lr, #(0x3334/2) 2124 movw r8, #(0x5556/2) 2125 it ne 2126 movne lr, r8 2127 vdup.16 d18, lr 2128 vqdmulh.s16 d0, d0, d18 21291: 2130 vdup.16 q0, d0[0] 2131 b L(ipred_cfl_splat_w16) 2132endfunc 2133 2134// void cfl_ac_420_8bpc_neon(int16_t *const ac, const pixel *const ypx, 2135// const ptrdiff_t stride, const int w_pad, 2136// const int h_pad, const int cw, const int ch); 2137function ipred_cfl_ac_420_8bpc_neon, export=1 2138 push {r4-r8,lr} 2139 ldrd r4, r5, [sp, #24] 2140 ldr r6, [sp, #32] 2141 clz r8, r5 2142 lsl r4, r4, #2 2143 adr r7, L(ipred_cfl_ac_420_tbl) 2144 sub r8, r8, #27 2145 ldr r8, [r7, r8, lsl #2] 2146 vmov.i16 q8, #0 2147 vmov.i16 q9, #0 2148 vmov.i16 q10, #0 2149 vmov.i16 q11, #0 2150 add r7, r7, r8 2151 sub r8, r6, r4 // height - h_pad 2152 rbit lr, r5 // rbit(width) 2153 rbit r12, r6 // rbit(height) 2154 clz lr, lr // ctz(width) 2155 clz r12, r12 // ctz(height) 2156 add lr, lr, r12 // log2sz 2157 add r12, r1, r2 2158 vdup.32 d31, lr 2159 lsl r2, r2, #1 2160 vneg.s32 d31, d31 // -log2sz 2161 bx r7 2162 2163 .align 2 2164L(ipred_cfl_ac_420_tbl): 2165 .word L(ipred_cfl_ac_420_w16) - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB 2166 .word L(ipred_cfl_ac_420_w8) - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB 2167 .word L(ipred_cfl_ac_420_w4) - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB 2168 2169L(ipred_cfl_ac_420_w4): 21701: // Copy and subsample input 2171 vld1.8 {d0}, [r1, :64], r2 2172 vld1.8 {d2}, [r12, :64], r2 2173 vld1.8 {d1}, [r1, :64], r2 2174 vld1.8 {d3}, [r12, :64], r2 2175 vpaddl.u8 q0, q0 2176 vpaddl.u8 q1, q1 2177 vadd.i16 q0, q0, q1 2178 vshl.i16 q0, q0, #1 2179 subs r8, r8, #2 2180 vst1.16 {q0}, [r0, :128]! 2181 vadd.i16 q8, q8, q0 2182 bgt 1b 2183 cmp r4, #0 2184 vmov d0, d1 2185 vmov d2, d1 2186 vmov d3, d1 2187L(ipred_cfl_ac_420_w4_hpad): 2188 beq 3f // This assumes that all callers already did "cmp r4, #0" 21892: // Vertical padding (h_pad > 0) 2190 subs r4, r4, #4 2191 vst1.16 {q0, q1}, [r0, :128]! 2192 vadd.i16 q8, q8, q0 2193 vadd.i16 q8, q8, q1 2194 bgt 2b 21953: 2196L(ipred_cfl_ac_420_w4_calc_subtract_dc): 2197 // Aggregate the sums 2198 vadd.i16 q0, q8, q9 2199 vadd.i16 q1, q10, q11 2200 vpaddl.u16 q0, q0 2201 vpaddl.u16 q1, q1 2202 vadd.i32 q0, q1 2203 vadd.i32 d0, d0, d1 2204 vpadd.i32 d0, d0, d0 // sum 2205 sub r0, r0, r6, lsl #3 2206 vrshl.u32 d16, d0, d31 // (sum + (1 << (log2sz - 1))) >>= log2sz 2207 vdup.16 q8, d16[0] 2208L(ipred_cfl_ac_420_w4_subtract_dc): 22096: // Subtract dc from ac 2210 vld1.16 {q0, q1}, [r0, :128] 2211 subs r6, r6, #4 2212 vsub.i16 q0, q0, q8 2213 vsub.i16 q1, q1, q8 2214 vst1.16 {q0, q1}, [r0, :128]! 2215 bgt 6b 2216 pop {r4-r8, pc} 2217 2218L(ipred_cfl_ac_420_w8): 2219 cmp r3, #0 2220 bne L(ipred_cfl_ac_420_w8_wpad) 22211: // Copy and subsample input, without padding 2222 vld1.8 {q0}, [r1, :128], r2 2223 vld1.8 {q1}, [r12, :128], r2 2224 vld1.8 {q2}, [r1, :128], r2 2225 vpaddl.u8 q0, q0 2226 vld1.8 {q3}, [r12, :128], r2 2227 vpaddl.u8 q1, q1 2228 vpaddl.u8 q2, q2 2229 vpaddl.u8 q3, q3 2230 vadd.i16 q0, q0, q1 2231 vadd.i16 q2, q2, q3 2232 vshl.i16 q0, q0, #1 2233 vshl.i16 q1, q2, #1 2234 subs r8, r8, #2 2235 vst1.16 {q0, q1}, [r0, :128]! 2236 vadd.i16 q8, q8, q0 2237 vadd.i16 q9, q9, q1 2238 bgt 1b 2239 cmp r4, #0 2240 vmov q0, q1 2241 b L(ipred_cfl_ac_420_w8_hpad) 2242 2243L(ipred_cfl_ac_420_w8_wpad): 22441: // Copy and subsample input, padding 4 2245 vld1.16 {d0}, [r1, :64], r2 2246 vld1.16 {d2}, [r12, :64], r2 2247 vld1.16 {d1}, [r1, :64], r2 2248 vld1.16 {d3}, [r12, :64], r2 2249 vpaddl.u8 q0, q0 2250 vpaddl.u8 q1, q1 2251 vadd.i16 q0, q0, q1 2252 vshl.i16 q0, q0, #1 2253 vdup.16 d3, d1[3] 2254 vmov d2, d1 2255 vdup.16 d1, d0[3] 2256 subs r8, r8, #2 2257 vst1.16 {q0, q1}, [r0, :128]! 2258 vadd.i16 q8, q8, q0 2259 vadd.i16 q9, q9, q1 2260 bgt 1b 2261 cmp r4, #0 2262 vmov q0, q1 2263 2264L(ipred_cfl_ac_420_w8_hpad): 2265 beq 3f // This assumes that all callers already did "cmp r4, #0" 22662: // Vertical padding (h_pad > 0) 2267 subs r4, r4, #4 2268 vst1.16 {q0, q1}, [r0, :128]! 2269 vadd.i16 q8, q8, q0 2270 vadd.i16 q9, q9, q1 2271 vst1.16 {q0, q1}, [r0, :128]! 2272 vadd.i16 q10, q10, q0 2273 vadd.i16 q11, q11, q1 2274 bgt 2b 22753: 2276 2277 // Double the height and reuse the w4 summing/subtracting 2278 lsl r6, r6, #1 2279 b L(ipred_cfl_ac_420_w4_calc_subtract_dc) 2280 2281L(ipred_cfl_ac_420_w16): 2282 adr r7, L(ipred_cfl_ac_420_w16_tbl) 2283 ldr r3, [r7, r3, lsl #2] 2284 add r7, r7, r3 2285 bx r7 2286 2287 .align 2 2288L(ipred_cfl_ac_420_w16_tbl): 2289 .word L(ipred_cfl_ac_420_w16_wpad0) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB 2290 .word L(ipred_cfl_ac_420_w16_wpad1) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB 2291 .word L(ipred_cfl_ac_420_w16_wpad2) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB 2292 .word L(ipred_cfl_ac_420_w16_wpad3) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB 2293 2294L(ipred_cfl_ac_420_w16_wpad0): 22951: // Copy and subsample input, without padding 2296 vld1.8 {q0, q1}, [r1, :128], r2 2297 vld1.8 {q2, q3}, [r12, :128], r2 2298 vpaddl.u8 q0, q0 2299 vld1.8 {q12, q13}, [r1, :128], r2 2300 vpaddl.u8 q1, q1 2301 vpaddl.u8 q2, q2 2302 vpaddl.u8 q3, q3 2303 vadd.i16 q0, q0, q2 2304 vadd.i16 q1, q1, q3 2305 vld1.8 {q2, q3}, [r12, :128], r2 2306 vpaddl.u8 q12, q12 2307 vpaddl.u8 q13, q13 2308 vpaddl.u8 q2, q2 2309 vpaddl.u8 q3, q3 2310 vadd.i16 q12, q12, q2 2311 vadd.i16 q13, q13, q3 2312 vshl.i16 q0, q0, #1 2313 vshl.i16 q1, q1, #1 2314 vshl.i16 q2, q12, #1 2315 vshl.i16 q3, q13, #1 2316 subs r8, r8, #2 2317 vst1.16 {q0, q1}, [r0, :128]! 2318 vadd.i16 q8, q8, q0 2319 vadd.i16 q9, q9, q1 2320 vst1.16 {q2, q3}, [r0, :128]! 2321 vadd.i16 q10, q10, q2 2322 vadd.i16 q11, q11, q3 2323 bgt 1b 2324 cmp r4, #0 2325 vmov q0, q2 2326 vmov q1, q3 2327 b L(ipred_cfl_ac_420_w16_hpad) 2328 2329L(ipred_cfl_ac_420_w16_wpad1): 23301: // Copy and subsample input, padding 4 2331 vldr d2, [r1, #16] 2332 vld1.8 {q0}, [r1, :128], r2 2333 vldr d6, [r12, #16] 2334 vld1.8 {q2}, [r12, :128], r2 2335 vpaddl.u8 d2, d2 2336 vldr d26, [r1, #16] 2337 vpaddl.u8 q0, q0 2338 vld1.8 {q12}, [r1, :128], r2 2339 vpaddl.u8 d6, d6 2340 vldr d30, [r12, #16] 2341 vpaddl.u8 q2, q2 2342 vld1.8 {q14}, [r12, :128], r2 2343 vpaddl.u8 d26, d26 2344 vpaddl.u8 q12, q12 2345 vpaddl.u8 d30, d30 2346 vpaddl.u8 q14, q14 2347 vadd.i16 d2, d2, d6 2348 vadd.i16 q0, q0, q2 2349 vadd.i16 d26, d26, d30 2350 vadd.i16 q12, q12, q14 2351 vshl.i16 d2, d2, #1 2352 vshl.i16 q0, q0, #1 2353 vshl.i16 d6, d26, #1 2354 vshl.i16 q2, q12, #1 2355 vdup.16 d3, d2[3] 2356 vdup.16 d7, d6[3] 2357 subs r8, r8, #2 2358 vst1.16 {q0, q1}, [r0, :128]! 2359 vadd.i16 q8, q8, q0 2360 vadd.i16 q9, q9, q1 2361 vst1.16 {q2, q3}, [r0, :128]! 2362 vadd.i16 q10, q10, q2 2363 vadd.i16 q11, q11, q3 2364 bgt 1b 2365 cmp r4, #0 2366 vmov q0, q2 2367 vmov q1, q3 2368 b L(ipred_cfl_ac_420_w16_hpad) 2369 2370L(ipred_cfl_ac_420_w16_wpad2): 23711: // Copy and subsample input, padding 8 2372 vld1.8 {q0}, [r1, :128], r2 2373 vld1.8 {q1}, [r12, :128], r2 2374 vld1.8 {q2}, [r1, :128], r2 2375 vpaddl.u8 q0, q0 2376 vld1.8 {q3}, [r12, :128], r2 2377 vpaddl.u8 q1, q1 2378 vpaddl.u8 q2, q2 2379 vpaddl.u8 q3, q3 2380 vadd.i16 q0, q0, q1 2381 vadd.i16 q2, q2, q3 2382 vshl.i16 q0, q0, #1 2383 vshl.i16 q2, q2, #1 2384 vdup.16 q1, d1[3] 2385 vdup.16 q3, d5[3] 2386 subs r8, r8, #2 2387 vst1.16 {q0, q1}, [r0, :128]! 2388 vadd.i16 q8, q8, q0 2389 vadd.i16 q9, q9, q1 2390 vst1.16 {q2, q3}, [r0, :128]! 2391 vadd.i16 q10, q10, q2 2392 vadd.i16 q11, q11, q3 2393 bgt 1b 2394 cmp r4, #0 2395 vmov q0, q2 2396 vmov q1, q3 2397 b L(ipred_cfl_ac_420_w16_hpad) 2398 2399L(ipred_cfl_ac_420_w16_wpad3): 24001: // Copy and subsample input, padding 12 2401 vld1.8 {d0}, [r1, :64], r2 2402 vld1.8 {d1}, [r12, :64], r2 2403 vld1.8 {d4}, [r1, :64], r2 2404 vpaddl.u8 q0, q0 2405 vld1.8 {d5}, [r12, :64], r2 2406 vpaddl.u8 q2, q2 2407 vadd.i16 d0, d0, d1 2408 vadd.i16 d4, d4, d5 2409 vshl.i16 d0, d0, #1 2410 vshl.i16 d4, d4, #1 2411 vdup.16 q1, d0[3] 2412 vdup.16 q3, d4[3] 2413 vdup.16 d1, d0[3] 2414 vdup.16 d5, d4[3] 2415 subs r8, r8, #2 2416 vst1.16 {q0, q1}, [r0, :128]! 2417 vadd.i16 q8, q8, q0 2418 vadd.i16 q9, q9, q1 2419 vst1.16 {q2, q3}, [r0, :128]! 2420 vadd.i16 q10, q10, q2 2421 vadd.i16 q11, q11, q3 2422 bgt 1b 2423 cmp r4, #0 2424 vmov q0, q2 2425 vmov q1, q3 2426 b L(ipred_cfl_ac_420_w16_hpad) 2427 2428L(ipred_cfl_ac_420_w16_hpad): 2429 beq 3f // This assumes that all callers already did "cmp r4, #0" 24302: // Vertical padding (h_pad > 0) 2431 subs r4, r4, #2 2432 vst1.16 {q0, q1}, [r0, :128]! 2433 vadd.i16 q8, q8, q0 2434 vadd.i16 q9, q9, q1 2435 vst1.16 {q2, q3}, [r0, :128]! 2436 vadd.i16 q10, q10, q2 2437 vadd.i16 q11, q11, q3 2438 bgt 2b 24393: 2440 2441 // Quadruple the height and reuse the w4 summing/subtracting 2442 lsl r6, r6, #2 2443 b L(ipred_cfl_ac_420_w4_calc_subtract_dc) 2444endfunc 2445 2446// void cfl_ac_422_8bpc_neon(int16_t *const ac, const pixel *const ypx, 2447// const ptrdiff_t stride, const int w_pad, 2448// const int h_pad, const int cw, const int ch); 2449function ipred_cfl_ac_422_8bpc_neon, export=1 2450 push {r4-r8,lr} 2451 ldrd r4, r5, [sp, #24] 2452 ldr r6, [sp, #32] 2453 clz r8, r5 2454 lsl r4, r4, #2 2455 adr r7, L(ipred_cfl_ac_422_tbl) 2456 sub r8, r8, #27 2457 ldr r8, [r7, r8, lsl #2] 2458 vmov.i16 q8, #0 2459 vmov.i16 q9, #0 2460 vmov.i16 q10, #0 2461 vmov.i16 q11, #0 2462 add r7, r7, r8 2463 sub r8, r6, r4 // height - h_pad 2464 rbit lr, r5 // rbit(width) 2465 rbit r12, r6 // rbit(height) 2466 clz lr, lr // ctz(width) 2467 clz r12, r12 // ctz(height) 2468 add lr, lr, r12 // log2sz 2469 add r12, r1, r2 2470 vdup.32 d31, lr 2471 lsl r2, r2, #1 2472 vneg.s32 d31, d31 // -log2sz 2473 bx r7 2474 2475 .align 2 2476L(ipred_cfl_ac_422_tbl): 2477 .word L(ipred_cfl_ac_422_w16) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB 2478 .word L(ipred_cfl_ac_422_w8) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB 2479 .word L(ipred_cfl_ac_422_w4) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB 2480 2481L(ipred_cfl_ac_422_w4): 24821: // Copy and subsample input 2483 vld1.8 {d0}, [r1, :64], r2 2484 vld1.8 {d1}, [r12, :64], r2 2485 vld1.8 {d2}, [r1, :64], r2 2486 vld1.8 {d3}, [r12, :64], r2 2487 vpaddl.u8 q0, q0 2488 vpaddl.u8 q1, q1 2489 vshl.i16 q0, q0, #2 2490 vshl.i16 q1, q1, #2 2491 subs r8, r8, #4 2492 vst1.16 {q0, q1}, [r0, :128]! 2493 vadd.i16 q8, q8, q0 2494 vadd.i16 q9, q9, q1 2495 bgt 1b 2496 cmp r4, #0 2497 vmov d0, d3 2498 vmov d1, d3 2499 vmov d2, d3 2500 b L(ipred_cfl_ac_420_w4_hpad) 2501 2502L(ipred_cfl_ac_422_w8): 2503 cmp r3, #0 2504 bne L(ipred_cfl_ac_422_w8_wpad) 25051: // Copy and subsample input, without padding 2506 vld1.8 {q0}, [r1, :128], r2 2507 vld1.8 {q1}, [r12, :128], r2 2508 vld1.8 {q2}, [r1, :128], r2 2509 vpaddl.u8 q0, q0 2510 vld1.8 {q3}, [r12, :128], r2 2511 vpaddl.u8 q1, q1 2512 vpaddl.u8 q2, q2 2513 vpaddl.u8 q3, q3 2514 vshl.i16 q0, q0, #2 2515 vshl.i16 q1, q1, #2 2516 vshl.i16 q2, q2, #2 2517 vshl.i16 q3, q3, #2 2518 subs r8, r8, #4 2519 vst1.16 {q0, q1}, [r0, :128]! 2520 vadd.i16 q8, q8, q0 2521 vadd.i16 q9, q9, q1 2522 vst1.16 {q2, q3}, [r0, :128]! 2523 vadd.i16 q10, q10, q2 2524 vadd.i16 q11, q11, q3 2525 bgt 1b 2526 cmp r4, #0 2527 vmov q0, q3 2528 vmov q1, q3 2529 b L(ipred_cfl_ac_420_w8_hpad) 2530 2531L(ipred_cfl_ac_422_w8_wpad): 25321: // Copy and subsample input, padding 4 2533 vld1.8 {d0}, [r1, :64], r2 2534 vld1.8 {d1}, [r12, :64], r2 2535 vld1.8 {d2}, [r1, :64], r2 2536 vld1.8 {d3}, [r12, :64], r2 2537 vpaddl.u8 q0, q0 2538 vpaddl.u8 q1, q1 2539 vshl.i16 q0, q0, #2 2540 vshl.i16 q1, q1, #2 2541 vdup.16 d7, d3[3] 2542 vmov d6, d3 2543 vdup.16 d5, d2[3] 2544 vmov d4, d2 2545 vdup.16 d3, d1[3] 2546 vmov d2, d1 2547 vdup.16 d1, d0[3] 2548 subs r8, r8, #4 2549 vst1.16 {q0, q1}, [r0, :128]! 2550 vadd.i16 q8, q8, q0 2551 vadd.i16 q9, q9, q1 2552 vst1.16 {q2, q3}, [r0, :128]! 2553 vadd.i16 q10, q10, q2 2554 vadd.i16 q11, q11, q3 2555 bgt 1b 2556 cmp r4, #0 2557 vmov q0, q3 2558 vmov q1, q3 2559 b L(ipred_cfl_ac_420_w8_hpad) 2560 2561L(ipred_cfl_ac_422_w16): 2562 adr r7, L(ipred_cfl_ac_422_w16_tbl) 2563 ldr r3, [r7, r3, lsl #2] 2564 add r7, r7, r3 2565 bx r7 2566 2567 .align 2 2568L(ipred_cfl_ac_422_w16_tbl): 2569 .word L(ipred_cfl_ac_422_w16_wpad0) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB 2570 .word L(ipred_cfl_ac_422_w16_wpad1) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB 2571 .word L(ipred_cfl_ac_422_w16_wpad2) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB 2572 .word L(ipred_cfl_ac_422_w16_wpad3) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB 2573 2574L(ipred_cfl_ac_422_w16_wpad0): 25751: // Copy and subsample input, without padding 2576 vld1.8 {q0, q1}, [r1, :128], r2 2577 vld1.8 {q2, q3}, [r12, :128], r2 2578 vpaddl.u8 q0, q0 2579 vpaddl.u8 q1, q1 2580 vpaddl.u8 q2, q2 2581 vpaddl.u8 q3, q3 2582 vshl.i16 q0, q0, #2 2583 vshl.i16 q1, q1, #2 2584 vshl.i16 q2, q2, #2 2585 vshl.i16 q3, q3, #2 2586 subs r8, r8, #2 2587 vst1.16 {q0, q1}, [r0, :128]! 2588 vadd.i16 q8, q8, q0 2589 vadd.i16 q9, q9, q1 2590 vst1.16 {q2, q3}, [r0, :128]! 2591 vadd.i16 q10, q10, q2 2592 vadd.i16 q11, q11, q3 2593 bgt 1b 2594 cmp r4, #0 2595 vmov q0, q2 2596 vmov q1, q3 2597 b L(ipred_cfl_ac_420_w16_hpad) 2598 2599L(ipred_cfl_ac_422_w16_wpad1): 26001: // Copy and subsample input, padding 4 2601 vldr d2, [r1, #16] 2602 vld1.8 {q0}, [r1, :128], r2 2603 vldr d6, [r12, #16] 2604 vld1.8 {q2}, [r12, :128], r2 2605 vpaddl.u8 d2, d2 2606 vpaddl.u8 q0, q0 2607 vpaddl.u8 d6, d6 2608 vpaddl.u8 q2, q2 2609 vshl.i16 d2, d2, #2 2610 vshl.i16 q0, q0, #2 2611 vshl.i16 d6, d6, #2 2612 vshl.i16 q2, q2, #2 2613 vdup.16 d3, d2[3] 2614 vdup.16 d7, d6[3] 2615 subs r8, r8, #2 2616 vst1.16 {q0, q1}, [r0, :128]! 2617 vadd.i16 q8, q8, q0 2618 vadd.i16 q9, q9, q1 2619 vst1.16 {q2, q3}, [r0, :128]! 2620 vadd.i16 q10, q10, q2 2621 vadd.i16 q11, q11, q3 2622 bgt 1b 2623 cmp r4, #0 2624 vmov q0, q2 2625 vmov q1, q3 2626 b L(ipred_cfl_ac_420_w16_hpad) 2627 2628L(ipred_cfl_ac_422_w16_wpad2): 26291: // Copy and subsample input, padding 8 2630 vld1.8 {q0}, [r1, :128], r2 2631 vld1.8 {q2}, [r12, :128], r2 2632 vpaddl.u8 q0, q0 2633 vpaddl.u8 q2, q2 2634 vshl.i16 q0, q0, #2 2635 vshl.i16 q2, q2, #2 2636 vdup.16 q1, d1[3] 2637 vdup.16 q3, d5[3] 2638 subs r8, r8, #2 2639 vst1.16 {q0, q1}, [r0, :128]! 2640 vadd.i16 q8, q8, q0 2641 vadd.i16 q9, q9, q1 2642 vst1.16 {q2, q3}, [r0, :128]! 2643 vadd.i16 q10, q10, q2 2644 vadd.i16 q11, q11, q3 2645 bgt 1b 2646 cmp r4, #0 2647 vmov q0, q2 2648 vmov q1, q3 2649 b L(ipred_cfl_ac_420_w16_hpad) 2650 2651L(ipred_cfl_ac_422_w16_wpad3): 26521: // Copy and subsample input, padding 12 2653 vld1.8 {d0}, [r1, :64], r2 2654 vld1.8 {d1}, [r12, :64], r2 2655 vpaddl.u8 q0, q0 2656 vshl.i16 q0, q0, #2 2657 vdup.16 q3, d1[3] 2658 vdup.16 q1, d0[3] 2659 vdup.16 d5, d1[3] 2660 vmov d4, d1 2661 vdup.16 d1, d0[3] 2662 subs r8, r8, #2 2663 vst1.16 {q0, q1}, [r0, :128]! 2664 vadd.i16 q8, q8, q0 2665 vadd.i16 q9, q9, q1 2666 vst1.16 {q2, q3}, [r0, :128]! 2667 vadd.i16 q10, q10, q2 2668 vadd.i16 q11, q11, q3 2669 bgt 1b 2670 cmp r4, #0 2671 vmov q0, q2 2672 vmov q1, q3 2673 b L(ipred_cfl_ac_420_w16_hpad) 2674endfunc 2675 2676// void cfl_ac_444_8bpc_neon(int16_t *const ac, const pixel *const ypx, 2677// const ptrdiff_t stride, const int w_pad, 2678// const int h_pad, const int cw, const int ch); 2679function ipred_cfl_ac_444_8bpc_neon, export=1 2680 push {r4-r8,lr} 2681 ldrd r4, r5, [sp, #24] 2682 ldr r6, [sp, #32] 2683 clz r8, r5 2684 lsl r4, r4, #2 2685 adr r7, L(ipred_cfl_ac_444_tbl) 2686 sub r8, r8, #26 2687 ldr r8, [r7, r8, lsl #2] 2688 vmov.i16 q8, #0 2689 vmov.i16 q9, #0 2690 vmov.i16 q10, #0 2691 vmov.i16 q11, #0 2692 add r7, r7, r8 2693 sub r8, r6, r4 // height - h_pad 2694 rbit lr, r5 // rbit(width) 2695 rbit r12, r6 // rbit(height) 2696 clz lr, lr // ctz(width) 2697 clz r12, r12 // ctz(height) 2698 add lr, lr, r12 // log2sz 2699 add r12, r1, r2 2700 vdup.32 d31, lr 2701 lsl r2, r2, #1 2702 vneg.s32 d31, d31 // -log2sz 2703 bx r7 2704 2705 .align 2 2706L(ipred_cfl_ac_444_tbl): 2707 .word L(ipred_cfl_ac_444_w32) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB 2708 .word L(ipred_cfl_ac_444_w16) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB 2709 .word L(ipred_cfl_ac_444_w8) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB 2710 .word L(ipred_cfl_ac_444_w4) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB 2711 2712L(ipred_cfl_ac_444_w4): 27131: // Copy and expand input 2714 vld1.32 {d0[]}, [r1, :32], r2 2715 vld1.32 {d0[1]}, [r12, :32], r2 2716 vld1.32 {d2[]}, [r1, :32], r2 2717 vld1.32 {d2[1]}, [r12, :32], r2 2718 vshll.u8 q0, d0, #3 2719 vshll.u8 q1, d2, #3 2720 subs r8, r8, #4 2721 vst1.16 {q0, q1}, [r0, :128]! 2722 vadd.i16 q8, q8, q0 2723 vadd.i16 q9, q9, q1 2724 bgt 1b 2725 cmp r4, #0 2726 vmov d0, d3 2727 vmov d1, d3 2728 vmov d2, d3 2729 b L(ipred_cfl_ac_420_w4_hpad) 2730 2731L(ipred_cfl_ac_444_w8): 27321: // Copy and expand input 2733 vld1.16 {d0}, [r1, :64], r2 2734 vld1.16 {d2}, [r12, :64], r2 2735 vld1.16 {d4}, [r1, :64], r2 2736 vshll.u8 q0, d0, #3 2737 vld1.16 {d6}, [r12, :64], r2 2738 vshll.u8 q1, d2, #3 2739 vshll.u8 q2, d4, #3 2740 vshll.u8 q3, d6, #3 2741 subs r8, r8, #4 2742 vst1.16 {q0, q1}, [r0, :128]! 2743 vadd.i16 q8, q8, q0 2744 vadd.i16 q9, q9, q1 2745 vst1.16 {q2, q3}, [r0, :128]! 2746 vadd.i16 q10, q10, q2 2747 vadd.i16 q11, q11, q3 2748 bgt 1b 2749 cmp r4, #0 2750 vmov q0, q3 2751 vmov q1, q3 2752 b L(ipred_cfl_ac_420_w8_hpad) 2753 2754L(ipred_cfl_ac_444_w16): 2755 cmp r3, #0 2756 bne L(ipred_cfl_ac_444_w16_wpad) 27571: // Copy and expand input, without padding 2758 vld1.8 {q1}, [r1, :128], r2 2759 vld1.8 {q3}, [r12, :128], r2 2760 vshll.u8 q0, d2, #3 2761 vshll.u8 q1, d3, #3 2762 vshll.u8 q2, d6, #3 2763 vshll.u8 q3, d7, #3 2764 subs r8, r8, #2 2765 vst1.16 {q0, q1}, [r0, :128]! 2766 vadd.i16 q8, q8, q0 2767 vadd.i16 q9, q9, q1 2768 vst1.16 {q2, q3}, [r0, :128]! 2769 vadd.i16 q10, q10, q2 2770 vadd.i16 q11, q11, q3 2771 bgt 1b 2772 cmp r4, #0 2773 vmov q0, q2 2774 vmov q1, q3 2775 b L(ipred_cfl_ac_420_w16_hpad) 2776 2777L(ipred_cfl_ac_444_w16_wpad): 27781: // Copy and expand input, padding 8 2779 vld1.8 {d0}, [r1, :64], r2 2780 vld1.8 {d4}, [r12, :64], r2 2781 vshll.u8 q0, d0, #3 2782 vshll.u8 q2, d4, #3 2783 vdup.16 q1, d1[3] 2784 vdup.16 q3, d5[3] 2785 subs r8, r8, #2 2786 vst1.16 {q0, q1}, [r0, :128]! 2787 vadd.i16 q8, q8, q0 2788 vadd.i16 q9, q9, q1 2789 vst1.16 {q2, q3}, [r0, :128]! 2790 vadd.i16 q10, q10, q2 2791 vadd.i16 q11, q11, q3 2792 bgt 1b 2793 cmp r4, #0 2794 vmov q0, q2 2795 vmov q1, q3 2796 b L(ipred_cfl_ac_420_w16_hpad) 2797 2798L(ipred_cfl_ac_444_w32): 2799 adr r7, L(ipred_cfl_ac_444_w32_tbl) 2800 ldr r3, [r7, r3, lsl #1] // (w3>>1) << 2 2801 add r7, r7, r3 2802 bx r7 2803 2804 .align 2 2805L(ipred_cfl_ac_444_w32_tbl): 2806 .word L(ipred_cfl_ac_444_w32_wpad0) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB 2807 .word L(ipred_cfl_ac_444_w32_wpad2) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB 2808 .word L(ipred_cfl_ac_444_w32_wpad4) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB 2809 .word L(ipred_cfl_ac_444_w32_wpad6) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB 2810 2811L(ipred_cfl_ac_444_w32_wpad0): 28121: // Copy and expand input, without padding 2813 vld1.8 {q2, q3}, [r1, :128], r2 2814 vld1.8 {q13, q14}, [r12, :128], r2 2815 vshll.u8 q0, d4, #3 2816 vshll.u8 q1, d5, #3 2817 vshll.u8 q2, d6, #3 2818 vshll.u8 q3, d7, #3 2819 vshll.u8 q12, d26, #3 2820 vshll.u8 q13, d27, #3 2821 subs r8, r8, #2 2822 vst1.16 {q0, q1}, [r0, :128]! 2823 vadd.i16 q8, q8, q0 2824 vadd.i16 q9, q9, q1 2825 vshll.u8 q0, d28, #3 2826 vshll.u8 q1, d29, #3 2827 vst1.16 {q2, q3}, [r0, :128]! 2828 vadd.i16 q10, q10, q2 2829 vadd.i16 q11, q11, q3 2830 vst1.16 {q12, q13}, [r0, :128]! 2831 vadd.i16 q8, q8, q12 2832 vadd.i16 q9, q9, q13 2833 vst1.16 {q0, q1}, [r0, :128]! 2834 vadd.i16 q10, q10, q0 2835 vadd.i16 q11, q11, q1 2836 bgt 1b 2837 cmp r4, #0 2838 b L(ipred_cfl_ac_444_w32_hpad) 2839 2840L(ipred_cfl_ac_444_w32_wpad2): 28411: // Copy and expand input, padding 8 2842 vldr d4, [r1, #16] 2843 vld1.8 {q1}, [r1, :128], r2 2844 vldr d28, [r12, #16] 2845 vld1.8 {q13}, [r12, :128], r2 2846 vshll.u8 q2, d4, #3 2847 vshll.u8 q0, d2, #3 2848 vshll.u8 q1, d3, #3 2849 vshll.u8 q12, d26, #3 2850 vshll.u8 q13, d27, #3 2851 vdup.16 q3, d5[3] 2852 subs r8, r8, #2 2853 vst1.16 {q0, q1}, [r0, :128]! 2854 vadd.i16 q8, q8, q0 2855 vadd.i16 q9, q9, q1 2856 vshll.u8 q0, d28, #3 2857 vst1.16 {q2, q3}, [r0, :128]! 2858 vadd.i16 q10, q10, q2 2859 vadd.i16 q11, q11, q3 2860 vdup.16 q1, d1[3] 2861 vst1.16 {q12, q13}, [r0, :128]! 2862 vadd.i16 q8, q8, q12 2863 vadd.i16 q9, q9, q13 2864 vst1.16 {q0, q1}, [r0, :128]! 2865 vadd.i16 q10, q10, q0 2866 vadd.i16 q11, q11, q1 2867 bgt 1b 2868 cmp r4, #0 2869 b L(ipred_cfl_ac_444_w32_hpad) 2870 2871L(ipred_cfl_ac_444_w32_wpad4): 28721: // Copy and expand input, padding 16 2873 vld1.8 {q1}, [r1, :128], r2 2874 vld1.8 {q13}, [r12, :128], r2 2875 vshll.u8 q0, d2, #3 2876 vshll.u8 q1, d3, #3 2877 vshll.u8 q12, d26, #3 2878 vshll.u8 q13, d27, #3 2879 vdup.16 q2, d3[3] 2880 vdup.16 q3, d3[3] 2881 subs r8, r8, #2 2882 vst1.16 {q0, q1}, [r0, :128]! 2883 vadd.i16 q8, q8, q0 2884 vadd.i16 q9, q9, q1 2885 vdup.16 q0, d27[3] 2886 vdup.16 q1, d27[3] 2887 vst1.16 {q2, q3}, [r0, :128]! 2888 vadd.i16 q10, q10, q2 2889 vadd.i16 q11, q11, q3 2890 vst1.16 {q12, q13}, [r0, :128]! 2891 vadd.i16 q8, q8, q12 2892 vadd.i16 q9, q9, q13 2893 vst1.16 {q0, q1}, [r0, :128]! 2894 vadd.i16 q10, q10, q0 2895 vadd.i16 q11, q11, q1 2896 bgt 1b 2897 cmp r4, #0 2898 b L(ipred_cfl_ac_444_w32_hpad) 2899 2900L(ipred_cfl_ac_444_w32_wpad6): 29011: // Copy and expand input, padding 24 2902 vld1.8 {d0}, [r1, :64], r2 2903 vld1.8 {d24}, [r12, :64], r2 2904 vshll.u8 q0, d0, #3 2905 vshll.u8 q12, d24, #3 2906 subs r8, r8, #2 2907 vdup.16 q1, d1[3] 2908 vdup.16 q2, d1[3] 2909 vdup.16 q3, d1[3] 2910 vst1.16 {q0, q1}, [r0, :128]! 2911 vadd.i16 q8, q8, q0 2912 vadd.i16 q9, q9, q1 2913 vdup.16 q13, d25[3] 2914 vdup.16 q0, d25[3] 2915 vdup.16 q1, d25[3] 2916 vst1.16 {q2, q3}, [r0, :128]! 2917 vadd.i16 q10, q10, q2 2918 vadd.i16 q11, q11, q3 2919 vst1.16 {q12, q13}, [r0, :128]! 2920 vadd.i16 q8, q8, q12 2921 vadd.i16 q9, q9, q13 2922 vst1.16 {q0, q1}, [r0, :128]! 2923 vadd.i16 q10, q10, q0 2924 vadd.i16 q11, q11, q1 2925 bgt 1b 2926 cmp r4, #0 2927 2928L(ipred_cfl_ac_444_w32_hpad): 2929 beq 3f // This assumes that all callers already did "cmp r4, #0" 29302: // Vertical padding (h_pad > 0) 2931 subs r4, r4, #1 2932 vst1.16 {q12, q13}, [r0, :128]! 2933 vadd.i16 q8, q8, q12 2934 vadd.i16 q9, q9, q13 2935 vst1.16 {q0, q1}, [r0, :128]! 2936 vadd.i16 q10, q10, q0 2937 vadd.i16 q11, q11, q1 2938 bgt 2b 29393: 2940 2941 // Multiply the height by eight and reuse the w4 subtracting 2942 lsl r6, r6, #3 2943 // Aggregate the sums, with wider intermediates earlier than in 2944 // ipred_cfl_ac_420_w8_calc_subtract_dc. 2945 vpaddl.u16 q0, q8 2946 vpaddl.u16 q1, q9 2947 vpaddl.u16 q2, q10 2948 vpaddl.u16 q3, q11 2949 vadd.i32 q0, q0, q1 2950 vadd.i32 q2, q2, q3 2951 vadd.i32 q0, q0, q2 2952 vadd.i32 d0, d0, d1 2953 vpadd.i32 d0, d0, d0 // sum 2954 sub r0, r0, r6, lsl #3 2955 vrshl.u32 d16, d0, d31 // (sum + (1 << (log2sz - 1))) >>= log2sz 2956 vdup.16 q8, d16[0] 2957 b L(ipred_cfl_ac_420_w4_subtract_dc) 2958endfunc 2959