1/****************************************************************************** 2 * Copyright © 2018, VideoLAN and dav1d authors 3 * Copyright © 2020, Martin Storsjo 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, this 10 * list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 *****************************************************************************/ 27 28#include "src/arm/asm.S" 29#include "util.S" 30 31// The exported functions in this file have got the following signature: 32// void itxfm_add(pixel *dst, ptrdiff_t dst_stride, coef *coeff, int eob); 33 34// Most of the functions use the following register layout: 35// r0-r3 external parameters 36// r4 function pointer to first transform 37// r5 function pointer to second transform 38// r6 output parameter for helper function 39// r7 input parameter for helper function 40// r8 input stride for helper function 41// r9 scratch variable for helper functions 42// r10-r11 pointer to list of eob thresholds, eob threshold value, 43// scratch variables within helper functions (backed up) 44 45// The SIMD registers most often use the following layout: 46// d0-d3 multiplication coefficients 47// d4-d7 scratch registers 48// d8-d15 unused in some transforms, used for scratch registers in others 49// d16-v31 inputs/outputs of transforms 50 51// Potential further optimizations, that are left unimplemented for now: 52// - Trying to keep multiplication coefficients in registers across multiple 53// transform functions. (The register layout is designed to potentially 54// allow this.) 55// - Use a simplified version of the transforms themselves for cases where 56// we know a significant number of inputs are zero. E.g. if the eob value 57// indicates only a quarter of input values are set, for idct16 and up, 58// a significant amount of calculation can be skipped, at the cost of more 59// code duplication and special casing. 60 61const idct_coeffs, align=4 62 // idct4 63 .short 2896, 2896*8, 1567, 3784 64 // idct8 65 .short 799, 4017, 3406, 2276 66 // idct16 67 .short 401, 4076, 3166, 2598 68 .short 1931, 3612, 3920, 1189 69 // idct32 70 .short 201, 4091, 3035, 2751 71 .short 1751, 3703, 3857, 1380 72 .short 995, 3973, 3513, 2106 73 .short 2440, 3290, 4052, 601 74endconst 75 76const idct64_coeffs, align=4 77 .short 101*8, 4095*8, 2967*8, -2824*8 78 .short 1660*8, 3745*8, 3822*8, -1474*8 79 .short 4076, 401, 4017, 799 80 81 .short 4036*8, -700*8, 2359*8, 3349*8 82 .short 3461*8, -2191*8, 897*8, 3996*8 83 .short -3166, -2598, -799, -4017 84 85 .short 501*8, 4065*8, 3229*8, -2520*8 86 .short 2019*8, 3564*8, 3948*8, -1092*8 87 .short 3612, 1931, 2276, 3406 88 89 .short 4085*8, -301*8, 2675*8, 3102*8 90 .short 3659*8, -1842*8, 1285*8, 3889*8 91 .short -3920, -1189, -3406, -2276 92endconst 93 94const iadst4_coeffs, align=4 95 // .h[4-5] can be interpreted as .s[2] 96 .short 1321, 3803, 2482, 3344, 3344, 0 97endconst 98 99const iadst8_coeffs, align=4 100 .short 4076, 401, 3612, 1931 101 .short 2598, 3166, 1189, 3920 102 // idct_coeffs 103 .short 2896, 0, 1567, 3784, 0, 0, 0, 0 104endconst 105 106const iadst16_coeffs, align=4 107 .short 4091, 201, 3973, 995 108 .short 3703, 1751, 3290, 2440 109 .short 2751, 3035, 2106, 3513 110 .short 1380, 3857, 601, 4052 111endconst 112 113.macro vmull_vmlal d0, s0, s1, c0, c1 114 vmull.s16 \d0, \s0, \c0 115 vmlal.s16 \d0, \s1, \c1 116.endm 117 118.macro vmull_vmlal_8h d0, d1, s0, s1, s2, s3, c0, c1 119 vmull.s16 \d0, \s0, \c0 120 vmlal.s16 \d0, \s2, \c1 121 vmull.s16 \d1, \s1, \c0 122 vmlal.s16 \d1, \s3, \c1 123.endm 124 125.macro vmull_vmlsl d0, s0, s1, c0, c1 126 vmull.s16 \d0, \s0, \c0 127 vmlsl.s16 \d0, \s1, \c1 128.endm 129 130.macro vmull_vmlsl_8h d0, d1, s0, s1, s2, s3, c0, c1 131 vmull.s16 \d0, \s0, \c0 132 vmlsl.s16 \d0, \s2, \c1 133 vmull.s16 \d1, \s1, \c0 134 vmlsl.s16 \d1, \s3, \c1 135.endm 136 137.macro vqrshrn_8h d0, d1, s0, s1, shift 138 vqrshrn.s32 \d0, \s0, \shift 139 vqrshrn.s32 \d1, \s1, \shift 140.endm 141 142.macro scale_input c, r0, r1, r2 r3, r4, r5, r6, r7 143 vqrdmulh.s16 \r0, \r0, \c 144 vqrdmulh.s16 \r1, \r1, \c 145.ifnb \r2 146 vqrdmulh.s16 \r2, \r2, \c 147 vqrdmulh.s16 \r3, \r3, \c 148.endif 149.ifnb \r4 150 vqrdmulh.s16 \r4, \r4, \c 151 vqrdmulh.s16 \r5, \r5, \c 152 vqrdmulh.s16 \r6, \r6, \c 153 vqrdmulh.s16 \r7, \r7, \c 154.endif 155.endm 156 157.macro load_add_store load, shift, addsrc, adddst, narrowsrc, narrowdst, store, dst, src, shiftbits=4 158.ifnb \load 159 vld1.8 {\load}, [\src, :64], r1 160.endif 161.ifnb \shift 162 vrshr.s16 \shift, \shift, #\shiftbits 163.endif 164.ifnb \addsrc 165 vaddw.u8 \adddst, \adddst, \addsrc 166.endif 167.ifnb \narrowsrc 168 vqmovun.s16 \narrowdst, \narrowsrc 169.endif 170.ifnb \store 171 vst1.8 {\store}, [\dst, :64], r1 172.endif 173.endm 174.macro load_add_store_8x8 dst, src, shiftbits=4 175 mov \src, \dst 176 load_add_store d2, q8, , , , , , \dst, \src, \shiftbits 177 load_add_store d3, q9, , , , , , \dst, \src, \shiftbits 178 load_add_store d4, q10, d2, q8, , , , \dst, \src, \shiftbits 179 load_add_store d5, q11, d3, q9, q8, d2, , \dst, \src, \shiftbits 180 load_add_store d6, q12, d4, q10, q9, d3, d2, \dst, \src, \shiftbits 181 load_add_store d7, q13, d5, q11, q10, d4, d3, \dst, \src, \shiftbits 182 load_add_store d2, q14, d6, q12, q11, d5, d4, \dst, \src, \shiftbits 183 load_add_store d3, q15, d7, q13, q12, d6, d5, \dst, \src, \shiftbits 184 load_add_store , , d2, q14, q13, d7, d6, \dst, \src, \shiftbits 185 load_add_store , , d3, q15, q14, d2, d7, \dst, \src, \shiftbits 186 load_add_store , , , , q15, d3, d2, \dst, \src, \shiftbits 187 load_add_store , , , , , , d3, \dst, \src, \shiftbits 188.endm 189.macro load_add_store_8x4 dst, src 190 mov \src, \dst 191 load_add_store d2, q8, , , , , , \dst, \src 192 load_add_store d3, q9, , , , , , \dst, \src 193 load_add_store d4, q10, d2, q8, , , , \dst, \src 194 load_add_store d5, q11, d3, q9, q8, d2, , \dst, \src 195 load_add_store , , d4, q10, q9, d3, d2, \dst, \src 196 load_add_store , , d5, q11, q10, d4, d3, \dst, \src 197 load_add_store , , , , q11, d5, d4, \dst, \src 198 load_add_store , , , , , , d5, \dst, \src 199.endm 200.macro load_add_store4 load, shift, addsrc, adddst, narrowsrc, narrowdst, store, dst, src 201.ifnb \load 202 vld1.32 {\load[0]}, [\src, :32], r1 203.endif 204.ifnb \shift 205 vrshr.s16 \shift, \shift, #4 206.endif 207.ifnb \load 208 vld1.32 {\load[1]}, [\src, :32], r1 209.endif 210.ifnb \addsrc 211 vaddw.u8 \adddst, \adddst, \addsrc 212.endif 213.ifnb \store 214 vst1.32 {\store[0]}, [\dst, :32], r1 215.endif 216.ifnb \narrowsrc 217 vqmovun.s16 \narrowdst, \narrowsrc 218.endif 219.ifnb \store 220 vst1.32 {\store[1]}, [\dst, :32], r1 221.endif 222.endm 223.macro load_add_store_4x16 dst, src 224 mov \src, \dst 225 load_add_store4 d0, , , , , , , \dst, \src 226 load_add_store4 d1, q8, , , , , , \dst, \src 227 load_add_store4 d2, q9, d0, q8, , , , \dst, \src 228 load_add_store4 d3, q10, d1, q9, q8, d0, , \dst, \src 229 load_add_store4 d4, q11, d2, q10, q9, d1, d0, \dst, \src 230 load_add_store4 d5, q12, d3, q11, q10, d2, d1, \dst, \src 231 load_add_store4 d6, q13, d4, q12, q11, d3, d2, \dst, \src 232 load_add_store4 d7, q14, d5, q13, q12, d4, d3, \dst, \src 233 load_add_store4 , q15, d6, q14, q13, d5, d4, \dst, \src 234 load_add_store4 , , d7, q15, q14, d6, d5, \dst, \src 235 load_add_store4 , , , , q15, d7, d6, \dst, \src 236 load_add_store4 , , , , , , d7, \dst, \src 237.endm 238.macro load_add_store_4x8 dst, src 239 mov \src, \dst 240 load_add_store4 d0, , , , , , , \dst, \src 241 load_add_store4 d1, q8, , , , , , \dst, \src 242 load_add_store4 d2, q9, d0, q8, , , , \dst, \src 243 load_add_store4 d3, q10, d1, q9, q8, d0, , \dst, \src 244 load_add_store4 , q11, d2, q10, q9, d1, d0, \dst, \src 245 load_add_store4 , , d3, q11, q10, d2, d1, \dst, \src 246 load_add_store4 , , , , q11, d3, d2, \dst, \src 247 load_add_store4 , , , , , , d3, \dst, \src 248.endm 249 250.macro idct_dc w, h, shift 251 cmp r3, #0 252 bne 1f 253 vmov.i16 d30, #0 254 movw r12, #2896*8 255 vld1.16 {d16[]}, [r2, :16] 256 vdup.16 d0, r12 257 vqrdmulh.s16 d16, d16, d0[0] 258 vst1.16 {d30[0]}, [r2, :16] 259.if (\w == 2*\h) || (2*\w == \h) 260 vqrdmulh.s16 d16, d16, d0[0] 261.endif 262.if \shift > 0 263 vrshr.s16 d16, d16, #\shift 264.endif 265 vqrdmulh.s16 d20, d16, d0[0] 266 mov r3, #\h 267 vrshr.s16 d16, d20, #4 268 vrshr.s16 d17, d20, #4 269 b idct_dc_w\w\()_neon 2701: 271.endm 272 273function idct_dc_w4_neon 2741: 275 vld1.32 {d0[0]}, [r0, :32], r1 276 vld1.32 {d0[1]}, [r0, :32], r1 277 vld1.32 {d1[0]}, [r0, :32], r1 278 vld1.32 {d1[1]}, [r0, :32], r1 279 subs r3, r3, #4 280 sub r0, r0, r1, lsl #2 281 vaddw.u8 q10, q8, d0 282 vqmovun.s16 d0, q10 283 vaddw.u8 q11, q8, d1 284 vst1.32 {d0[0]}, [r0, :32], r1 285 vqmovun.s16 d1, q11 286 vst1.32 {d0[1]}, [r0, :32], r1 287 vst1.32 {d1[0]}, [r0, :32], r1 288 vst1.32 {d1[1]}, [r0, :32], r1 289 bgt 1b 290 bx lr 291endfunc 292 293function idct_dc_w8_neon 2941: 295 vld1.8 {d0}, [r0, :64], r1 296 vld1.8 {d1}, [r0, :64], r1 297 vld1.8 {d2}, [r0, :64], r1 298 vaddw.u8 q10, q8, d0 299 vld1.8 {d3}, [r0, :64], r1 300 sub r0, r0, r1, lsl #2 301 subs r3, r3, #4 302 vaddw.u8 q11, q8, d1 303 vqmovun.s16 d0, q10 304 vaddw.u8 q12, q8, d2 305 vqmovun.s16 d1, q11 306 vaddw.u8 q13, q8, d3 307 vst1.8 {d0}, [r0, :64], r1 308 vqmovun.s16 d2, q12 309 vst1.8 {d1}, [r0, :64], r1 310 vqmovun.s16 d3, q13 311 vst1.8 {d2}, [r0, :64], r1 312 vst1.8 {d3}, [r0, :64], r1 313 bgt 1b 314 bx lr 315endfunc 316 317function idct_dc_w16_neon 3181: 319 vld1.8 {q0}, [r0, :128], r1 320 vld1.8 {q1}, [r0, :128], r1 321 vld1.8 {q2}, [r0, :128], r1 322 subs r3, r3, #4 323 vaddw.u8 q10, q8, d0 324 vaddw.u8 q11, q8, d1 325 vld1.8 {q3}, [r0, :128], r1 326 vaddw.u8 q12, q8, d2 327 vaddw.u8 q13, q8, d3 328 sub r0, r0, r1, lsl #2 329 vaddw.u8 q14, q8, d4 330 vaddw.u8 q15, q8, d5 331 vqmovun.s16 d0, q10 332 vqmovun.s16 d1, q11 333 vaddw.u8 q10, q8, d6 334 vaddw.u8 q11, q8, d7 335 vqmovun.s16 d2, q12 336 vqmovun.s16 d3, q13 337 vqmovun.s16 d4, q14 338 vqmovun.s16 d5, q15 339 vst1.8 {q0}, [r0, :128], r1 340 vqmovun.s16 d6, q10 341 vqmovun.s16 d7, q11 342 vst1.8 {q1}, [r0, :128], r1 343 vst1.8 {q2}, [r0, :128], r1 344 vst1.8 {q3}, [r0, :128], r1 345 bgt 1b 346 bx lr 347endfunc 348 349function idct_dc_w32_neon 3501: 351 vld1.8 {q0, q1}, [r0, :128], r1 352 subs r3, r3, #2 353 vld1.8 {q2, q3}, [r0, :128], r1 354 vaddw.u8 q10, q8, d0 355 vaddw.u8 q11, q8, d1 356 vaddw.u8 q12, q8, d2 357 vaddw.u8 q13, q8, d3 358 sub r0, r0, r1, lsl #1 359 vaddw.u8 q14, q8, d4 360 vaddw.u8 q15, q8, d5 361 vqmovun.s16 d0, q10 362 vqmovun.s16 d1, q11 363 vaddw.u8 q10, q8, d6 364 vaddw.u8 q11, q8, d7 365 vqmovun.s16 d2, q12 366 vqmovun.s16 d3, q13 367 vqmovun.s16 d4, q14 368 vqmovun.s16 d5, q15 369 vst1.8 {q0, q1}, [r0, :128], r1 370 vqmovun.s16 d6, q10 371 vqmovun.s16 d7, q11 372 vst1.8 {q2, q3}, [r0, :128], r1 373 bgt 1b 374 bx lr 375endfunc 376 377function idct_dc_w64_neon 378 sub r1, r1, #32 3791: 380 vld1.8 {q0, q1}, [r0, :128]! 381 subs r3, r3, #1 382 vld1.8 {q2, q3}, [r0, :128] 383 vaddw.u8 q10, q8, d0 384 vaddw.u8 q11, q8, d1 385 vaddw.u8 q12, q8, d2 386 vaddw.u8 q13, q8, d3 387 sub r0, r0, #32 388 vaddw.u8 q14, q8, d4 389 vaddw.u8 q15, q8, d5 390 vqmovun.s16 d0, q10 391 vqmovun.s16 d1, q11 392 vaddw.u8 q10, q8, d6 393 vaddw.u8 q11, q8, d7 394 vqmovun.s16 d2, q12 395 vqmovun.s16 d3, q13 396 vqmovun.s16 d4, q14 397 vqmovun.s16 d5, q15 398 vst1.8 {q0, q1}, [r0, :128]! 399 vqmovun.s16 d6, q10 400 vqmovun.s16 d7, q11 401 vst1.8 {q2, q3}, [r0, :128], r1 402 bgt 1b 403 bx lr 404endfunc 405 406.macro iwht4 407 vadd.i16 d16, d16, d17 408 vsub.i16 d21, d18, d19 409 vsub.i16 d20, d16, d21 410 vshr.s16 d20, d20, #1 411 vsub.i16 d18, d20, d17 412 vsub.i16 d17, d20, d19 413 vadd.i16 d19, d21, d18 414 vsub.i16 d16, d16, d17 415.endm 416 417.macro idct_4h_x4 r0, r1, r2, r3 418 vmull_vmlal q3, \r1, \r3, d0[3], d0[2] 419 vmull_vmlsl q2, \r1, \r3, d0[2], d0[3] 420 vmull_vmlal q1, \r0, \r2, d0[0], d0[0] 421 vqrshrn.s32 d6, q3, #12 422 vqrshrn.s32 d7, q2, #12 423 vmull_vmlsl q2, \r0, \r2, d0[0], d0[0] 424 vqrshrn.s32 d2, q1, #12 425 vqrshrn.s32 d3, q2, #12 426 vqadd.s16 \r0, d2, d6 427 vqsub.s16 \r3, d2, d6 428 vqadd.s16 \r1, d3, d7 429 vqsub.s16 \r2, d3, d7 430.endm 431 432.macro idct_8h_x4 q0, q1, q2, q3, r0, r1, r2, r3, r4, r5, r6, r7 433 vmull_vmlal_8h q6, q7, \r2, \r3, \r6, \r7, d0[3], d0[2] 434 vmull_vmlsl_8h q4, q5, \r2, \r3, \r6, \r7, d0[2], d0[3] 435 vmull_vmlal_8h q2, q3, \r0, \r1, \r4, \r5, d0[0], d0[0] 436 vqrshrn_8h d12, d13, q6, q7, #12 437 vqrshrn_8h d14, d15, q4, q5, #12 438 vmull_vmlsl_8h q4, q5, \r0, \r1, \r4, \r5, d0[0], d0[0] 439 vqrshrn_8h d4, d5, q2, q3, #12 440 vqrshrn_8h d6, d7, q4, q5, #12 441 vqadd.s16 \q0, q2, q6 442 vqsub.s16 \q3, q2, q6 443 vqadd.s16 \q1, q3, q7 444 vqsub.s16 \q2, q3, q7 445.endm 446 447function inv_dct_4h_x4_neon, export=1 448 movrel_local r12, idct_coeffs 449 vld1.16 {d0}, [r12, :64] 450 idct_4h_x4 d16, d17, d18, d19 451 bx lr 452endfunc 453 454function inv_dct_8h_x4_neon, export=1 455 movrel_local r12, idct_coeffs 456 vld1.16 {d0}, [r12, :64] 457 idct_8h_x4 q8, q9, q10, q11, d16, d17, d18, d19, d20, d21, d22, d23 458 bx lr 459endfunc 460 461.macro iadst_4x4 o0, o1, o2, o3 462 movrel_local r12, iadst4_coeffs 463 vld1.16 {d0, d1}, [r12, :128] 464 465 vsubl.s16 q1, d16, d18 466 vmull.s16 q2, d16, d0[0] 467 vmlal.s16 q2, d18, d0[1] 468 vmlal.s16 q2, d19, d0[2] 469 vmull.s16 q10, d17, d0[3] 470 vaddw.s16 q1, q1, d19 471 vmull.s16 q3, d16, d0[2] 472 vmlsl.s16 q3, d18, d0[0] 473 vmlsl.s16 q3, d19, d0[1] 474 475 vadd.s32 q11, q2, q3 476 vmul.s32 q1, q1, d1[0] 477 vadd.s32 q2, q2, q10 478 vadd.s32 q3, q3, q10 479 vsub.s32 q11, q11, q10 480 481 vqrshrn.s32 \o0, q2, #12 482 vqrshrn.s32 \o2, q1, #12 483 vqrshrn.s32 \o1, q3, #12 484 vqrshrn.s32 \o3, q11, #12 485.endm 486 487function inv_adst_4h_x4_neon, export=1 488 iadst_4x4 d16, d17, d18, d19 489 bx lr 490endfunc 491 492function inv_flipadst_4h_x4_neon, export=1 493 iadst_4x4 d19, d18, d17, d16 494 bx lr 495endfunc 496 497.macro iadst_8x4 o0, o1, o2, o3, o4, o5, o6, o7 498 movrel_local r12, iadst4_coeffs 499 vld1.16 {d0, d1}, [r12, :128] 500 501 vsubl.s16 q2, d16, d20 502 vsubl.s16 q3, d17, d21 503 vmull.s16 q4, d16, d0[0] 504 vmlal.s16 q4, d20, d0[1] 505 vmlal.s16 q4, d22, d0[2] 506 vmull.s16 q5, d17, d0[0] 507 vmlal.s16 q5, d21, d0[1] 508 vmlal.s16 q5, d23, d0[2] 509 vaddw.s16 q2, q2, d22 510 vaddw.s16 q3, q3, d23 511 vmull.s16 q6, d16, d0[2] 512 vmlsl.s16 q6, d20, d0[0] 513 vmlsl.s16 q6, d22, d0[1] 514 vmull.s16 q7, d17, d0[2] 515 vmlsl.s16 q7, d21, d0[0] 516 vmlsl.s16 q7, d23, d0[1] 517 518 vmul.s32 q10, q2, d1[0] 519 vmul.s32 q11, q3, d1[0] 520 521 vmull.s16 q2, d18, d0[3] 522 vmull.s16 q3, d19, d0[3] 523 524 vadd.s32 q8, q4, q2 // out0 525 vadd.s32 q9, q5, q3 526 527 vadd.s32 q4, q4, q6 // out3 528 vadd.s32 q5, q5, q7 529 530 vadd.s32 q6, q6, q2 // out1 531 vadd.s32 q7, q7, q3 532 533 vsub.s32 q4, q4, q2 // out3 534 vsub.s32 q5, q5, q3 535 536 vqrshrn.s32 d20, q10, #12 537 vqrshrn.s32 d21, q11, #12 538 539 vqrshrn.s32 \o0, q8, #12 540 vqrshrn.s32 \o1, q9, #12 541 542.ifc \o4, d18 543 vmov q9, q10 544.endif 545 546 vqrshrn.s32 \o2, q6, #12 547 vqrshrn.s32 \o3, q7, #12 548 549 vqrshrn.s32 \o6, q4, #12 550 vqrshrn.s32 \o7, q5, #12 551.endm 552 553function inv_adst_8h_x4_neon, export=1 554 iadst_8x4 d16, d17, d18, d19, d20, d21, d22, d23 555 bx lr 556endfunc 557 558function inv_flipadst_8h_x4_neon, export=1 559 iadst_8x4 d22, d23, d20, d21, d18, d19, d16, d17 560 bx lr 561endfunc 562 563function inv_identity_4h_x4_neon, export=1 564 movw r12, #(5793-4096)*8 565 vdup.16 d0, r12 566 vqrdmulh.s16 q2, q8, d0[0] 567 vqrdmulh.s16 q3, q9, d0[0] 568 vqadd.s16 q8, q8, q2 569 vqadd.s16 q9, q9, q3 570 bx lr 571endfunc 572 573function inv_identity_8h_x4_neon, export=1 574 movw r12, #(5793-4096)*8 575 vdup.16 d0, r12 576 vqrdmulh.s16 q1, q8, d0[0] 577 vqrdmulh.s16 q2, q9, d0[0] 578 vqrdmulh.s16 q3, q10, d0[0] 579 vqadd.s16 q8, q8, q1 580 vqrdmulh.s16 q1, q11, d0[0] 581 vqadd.s16 q9, q9, q2 582 vqadd.s16 q10, q10, q3 583 vqadd.s16 q11, q11, q1 584 bx lr 585endfunc 586 587.macro identity_8x4_shift1 r0, r1, r2, r3, c 588.irp i, \r0, \r1, \r2, \r3 589 vqrdmulh.s16 q1, \i, \c 590 vrhadd.s16 \i, \i, q1 591.endr 592.endm 593 594function inv_txfm_add_wht_wht_4x4_8bpc_neon, export=1 595 push {r4-r5,lr} 596 vmov.i16 q15, #0 597 vld1.16 {d16, d17, d18, d19}, [r2, :128] 598 vst1.16 {q15}, [r2, :128]! 599 600 vshr.s16 q8, q8, #2 601 vshr.s16 q9, q9, #2 602 603 iwht4 604 605 vst1.16 {q15}, [r2, :128]! 606 transpose_4x4h q8, q9, d16, d17, d18, d19 607 608 iwht4 609 610 vld1.32 {d0[]}, [r0, :32], r1 611 vld1.32 {d0[1]}, [r0, :32], r1 612 vld1.32 {d1[]}, [r0, :32], r1 613 vld1.32 {d1[1]}, [r0, :32], r1 614 615 b L(itx_4x4_end) 616endfunc 617 618function inv_txfm_add_4x4_neon 619 vmov.i16 q15, #0 620 vld1.16 {d16, d17, d18, d19}, [r2, :128] 621 vst1.16 {q15}, [r2, :128]! 622 623 blx r4 624 625 vst1.16 {q15}, [r2, :128]! 626 transpose_4x4h q8, q9, d16, d17, d18, d19 627 628 blx r5 629 630 vld1.32 {d0[]}, [r0, :32], r1 631 vld1.32 {d0[1]}, [r0, :32], r1 632 vld1.32 {d1[]}, [r0, :32], r1 633 vld1.32 {d1[1]}, [r0, :32], r1 634 vrshr.s16 q8, q8, #4 635 vrshr.s16 q9, q9, #4 636 637L(itx_4x4_end): 638 sub r0, r0, r1, lsl #2 639 vaddw.u8 q8, q8, d0 640 vqmovun.s16 d0, q8 641 vaddw.u8 q9, q9, d1 642 vst1.32 {d0[0]}, [r0, :32], r1 643 vqmovun.s16 d1, q9 644 vst1.32 {d0[1]}, [r0, :32], r1 645 vst1.32 {d1[0]}, [r0, :32], r1 646 vst1.32 {d1[1]}, [r0, :32], r1 647 648 pop {r4-r5,pc} 649endfunc 650 651.macro def_fn_4x4 txfm1, txfm2 652function inv_txfm_add_\txfm1\()_\txfm2\()_4x4_8bpc_neon, export=1 653 push {r4-r5,lr} 654 655.ifc \txfm1\()_\txfm2, dct_dct 656 cmp r3, #0 657 bne 1f 658 vmov.i16 d30, #0 659 movw r12, #2896*8 660 vld1.16 {d16[]}, [r2, :16] 661 vdup.16 d4, r12 662 vst1.16 {d30[0]}, [r2, :16] 663 vqrdmulh.s16 d16, d16, d4[0] 664 vld1.32 {d0[0]}, [r0, :32], r1 665 vqrdmulh.s16 d20, d16, d4[0] 666 vld1.32 {d0[1]}, [r0, :32], r1 667 vrshr.s16 d16, d20, #4 668 vrshr.s16 d17, d20, #4 669 vld1.32 {d1[0]}, [r0, :32], r1 670 vmov q9, q8 671 vld1.32 {d1[1]}, [r0, :32], r1 672 b L(itx_4x4_end) 6731: 674.endif 675 movrel_local r4, inv_\txfm1\()_4h_x4_neon 676 movrel_local r5, inv_\txfm2\()_4h_x4_neon 677 b inv_txfm_add_4x4_neon 678endfunc 679.endm 680 681def_fn_4x4 dct, dct 682def_fn_4x4 identity, identity 683def_fn_4x4 dct, adst 684def_fn_4x4 dct, flipadst 685def_fn_4x4 dct, identity 686def_fn_4x4 adst, dct 687def_fn_4x4 adst, adst 688def_fn_4x4 adst, flipadst 689def_fn_4x4 flipadst, dct 690def_fn_4x4 flipadst, adst 691def_fn_4x4 flipadst, flipadst 692def_fn_4x4 identity, dct 693 694def_fn_4x4 adst, identity 695def_fn_4x4 flipadst, identity 696def_fn_4x4 identity, adst 697def_fn_4x4 identity, flipadst 698 699.macro idct_8h_x8 q0, q1, q2, q3, q4, q5, q6, q7, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15 700 idct_8h_x4 \q0, \q2, \q4, \q6, \r0, \r1, \r4, \r5, \r8, \r9, \r12, \r13 701 702 vmull_vmlsl_8h q2, q3, \r2, \r3, \r14, \r15, d1[0], d1[1] // -> t4a 703 vmull_vmlal_8h q4, q5, \r2, \r3, \r14, \r15, d1[1], d1[0] // -> t7a 704 vmull_vmlsl_8h q6, q7, \r10, \r11, \r6, \r7, d1[2], d1[3] // -> t5a 705 vqrshrn_8h \r2, \r3, q2, q3, #12 // t4a 706 vqrshrn_8h \r14, \r15, q4, q5, #12 // t7a 707 vmull_vmlal_8h q2, q3, \r10, \r11, \r6, \r7, d1[3], d1[2] // -> t6a 708 vqrshrn_8h \r6, \r7, q6, q7, #12 // t5a 709 vqrshrn_8h \r10, \r11, q2, q3, #12 // t6a 710 711 vqadd.s16 q2, \q1, \q3 // t4 712 vqsub.s16 \q1, \q1, \q3 // t5a 713 vqadd.s16 q3, \q7, \q5 // t7 714 vqsub.s16 \q3, \q7, \q5 // t6a 715 716 vmull_vmlsl_8h q4, q5, \r6, \r7, \r2, \r3, d0[0], d0[0] // -> t5 717 vmull_vmlal_8h q6, q7, \r6, \r7, \r2, \r3, d0[0], d0[0] // -> t6 718 vqrshrn_8h d8, d9, q4, q5, #12 // t5 719 vqrshrn_8h d10, d11, q6, q7, #12 // t6 720 721 vqsub.s16 \q7, \q0, q3 // out7 722 vqadd.s16 \q0, \q0, q3 // out0 723 vqadd.s16 \q1, \q2, q5 // out1 724 vqsub.s16 q6, \q2, q5 // out6 725 vqadd.s16 \q2, \q4, q4 // out2 726 vqsub.s16 \q5, \q4, q4 // out5 727 vqadd.s16 \q3, \q6, q2 // out3 728 vqsub.s16 \q4, \q6, q2 // out4 729 vmov \q6, q6 // out6 730.endm 731 732.macro idct_4h_x8 r0, r1, r2, r3, r4, r5, r6, r7 733 idct_4h_x4 \r0, \r2, \r4, \r6 734 735 vmull_vmlsl q1, \r1, \r7, d1[0], d1[1] // -> t4a 736 vmull_vmlal q2, \r1, \r7, d1[1], d1[0] // -> t7a 737 vmull_vmlsl q3, \r5, \r3, d1[2], d1[3] // -> t5a 738 vqrshrn.s32 \r1, q1, #12 // t4a 739 vmull_vmlal q1, \r5, \r3, d1[3], d1[2] // -> t6a 740 vqrshrn.s32 \r7, q2, #12 // t7a 741 vqrshrn.s32 \r3, q3, #12 // t5a 742 vqrshrn.s32 \r5, q1, #12 // taa 743 744 vqadd.s16 d2, \r1, \r3 // t4 745 vqsub.s16 \r1, \r1, \r3 // t5a 746 vqadd.s16 d3, \r7, \r5 // t7 747 vqsub.s16 \r3, \r7, \r5 // t6a 748 749 vmull_vmlsl q2, \r3, \r1, d0[0], d0[0] // -> t5 750 vmull_vmlal q3, \r3, \r1, d0[0], d0[0] // -> t6 751 vqrshrn.s32 d4, q2, #12 // t5 752 vqrshrn.s32 d5, q3, #12 // t6 753 754 vqsub.s16 \r7, \r0, d3 // out7 755 vqadd.s16 \r0, \r0, d3 // out0 756 vqadd.s16 \r1, \r2, d5 // out1 757 vqsub.s16 d6, \r2, d5 // out6 758 vqadd.s16 \r2, \r4, d4 // out2 759 vqsub.s16 \r5, \r4, d4 // out5 760 vqadd.s16 \r3, \r6, d2 // out3 761 vqsub.s16 \r4, \r6, d2 // out4 762 vmov \r6, d6 // out6 763.endm 764 765function inv_dct_8h_x8_neon, export=1 766 movrel_local r12, idct_coeffs 767 vld1.16 {q0}, [r12, :128] 768 idct_8h_x8 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 769 bx lr 770endfunc 771 772function inv_dct_4h_x8_neon, export=1 773 movrel_local r12, idct_coeffs 774 vld1.16 {q0}, [r12, :128] 775 idct_4h_x8 d16, d17, d18, d19, d20, d21, d22, d23 776 bx lr 777endfunc 778 779.macro iadst_8h_x8 q0, q1, q2, q3, q4, q5, q6, q7, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15 780 movrel_local r12, iadst8_coeffs 781 vld1.16 {d0, d1, d2}, [r12, :64] 782 783 vmull_vmlal_8h q2, q3, d30, d31, d16, d17, d0[0], d0[1] 784 vmull_vmlsl_8h q4, q5, d30, d31, d16, d17, d0[1], d0[0] 785 vmull_vmlal_8h q6, q7, d26, d27, d20, d21, d0[2], d0[3] 786 vqrshrn_8h d16, d17, q2, q3, #12 // t0a 787 vqrshrn_8h d30, d31, q4, q5, #12 // t1a 788 vmull_vmlsl_8h q2, q3, d26, d27, d20, d21, d0[3], d0[2] 789 vmull_vmlal_8h q4, q5, d22, d23, d24, d25, d1[0], d1[1] 790 vqrshrn_8h d20, d21, q6, q7, #12 // t2a 791 vqrshrn_8h d26, d27, q2, q3, #12 // t3a 792 vmull_vmlsl_8h q6, q7, d22, d23, d24, d25, d1[1], d1[0] 793 vmull_vmlal_8h q2, q3, d18, d19, d28, d29, d1[2], d1[3] 794 vqrshrn_8h d24, d25, q4, q5, #12 // t4a 795 vqrshrn_8h d22, d23, q6, q7, #12 // t5a 796 vmull_vmlsl_8h q4, q5, d18, d19, d28, d29, d1[3], d1[2] 797 vqrshrn_8h d28, d29, q2, q3, #12 // t6a 798 vqrshrn_8h d18, d19, q4, q5, #12 // t7a 799 800 vqadd.s16 q2, q8, q12 // t0 801 vqsub.s16 q3, q8, q12 // t4 802 vqadd.s16 q4, q15, q11 // t1 803 vqsub.s16 q5, q15, q11 // t5 804 vqadd.s16 q6, q10, q14 // t2 805 vqsub.s16 q7, q10, q14 // t6 806 vqadd.s16 q10, q13, q9 // t3 807 vqsub.s16 q11, q13, q9 // t7 808 809 vmull_vmlal_8h q8, q9, d6, d7, d10, d11, d2[3], d2[2] 810 vmull_vmlsl_8h q12, q13, d6, d7, d10, d11, d2[2], d2[3] 811 vmull_vmlsl_8h q14, q15, d22, d23, d14, d15, d2[3], d2[2] 812 813 vqrshrn_8h d6, d7, q8, q9, #12 // t4a 814 vqrshrn_8h d10, d11, q12, q13, #12 // t5a 815 816 vmull_vmlal_8h q8, q9, d22, d23, d14, d15, d2[2], d2[3] 817 818 vqrshrn_8h d14, d15, q14, q15, #12 // t6a 819 vqrshrn_8h d22, d23, q8, q9, #12 // t7a 820 821 vqadd.s16 \q0, q2, q6 // out0 822 vqsub.s16 q2, q2, q6 // t2 823 vqadd.s16 \q7, q4, q10 // out7 824 vqsub.s16 q4, q4, q10 // t3 825 vqneg.s16 \q7, \q7 // out7 826 827 vqadd.s16 \q1, q3, q7 // out1 828 vqsub.s16 q3, q3, q7 // t6 829 vqadd.s16 \q6, q5, q11 // out6 830 vqsub.s16 q5, q5, q11 // t7 831 vqneg.s16 \q1, \q1 // out1 832 833 vmull_vmlal_8h q10, q11, d4, d5, d8, d9, d2[0], d2[0] // -> out3 (q11 or q12) 834 vmull_vmlsl_8h q6, q7, d4, d5, d8, d9, d2[0], d2[0] // -> out4 (q12 or q11) 835 vmull_vmlsl_8h q12, q13, d6, d7, d10, d11, d2[0], d2[0] // -> out5 (q13 or q10) 836 vqrshrn_8h d4, d5, q10, q11, #12 // out3 837 vmull_vmlal_8h q10, q11, d6, d7, d10, d11, d2[0], d2[0] // -> out2 (q10 or q13) 838 vqrshrn_8h d6, d7, q12, q13, #12 // out5 839 vqrshrn_8h \r4, \r5, q10, q11, #12 // out2 (q10 or q13) 840 vqrshrn_8h \r8, \r9, q6, q7, #12 // out4 (q12 or q11) 841 842 vqneg.s16 \q3, q2 // out3 843 vqneg.s16 \q5, q3 // out5 844.endm 845 846.macro iadst_4h_x8 r0, r1, r2, r3, r4, r5, r6, r7 847 movrel_local r12, iadst8_coeffs 848 vld1.16 {d0, d1, d2}, [r12, :64] 849 850 vmull_vmlal q2, d23, d16, d0[0], d0[1] 851 vmull_vmlsl q3, d23, d16, d0[1], d0[0] 852 vmull_vmlal q4, d21, d18, d0[2], d0[3] 853 vqrshrn.s32 d16, q2, #12 // t0a 854 vqrshrn.s32 d23, q3, #12 // t1a 855 vmull_vmlsl q5, d21, d18, d0[3], d0[2] 856 vmull_vmlal q6, d19, d20, d1[0], d1[1] 857 vqrshrn.s32 d18, q4, #12 // t2a 858 vqrshrn.s32 d21, q5, #12 // t3a 859 vmull_vmlsl q7, d19, d20, d1[1], d1[0] 860 vmull_vmlal q2, d17, d22, d1[2], d1[3] 861 vqrshrn.s32 d20, q6, #12 // t4a 862 vqrshrn.s32 d19, q7, #12 // t5a 863 vmull_vmlsl q3, d17, d22, d1[3], d1[2] 864 vqrshrn.s32 d22, q2, #12 // t6a 865 vqrshrn.s32 d17, q3, #12 // t7a 866 867 vqadd.s16 d4, d16, d20 // t0 868 vqsub.s16 d5, d16, d20 // t4 869 vqadd.s16 d6, d23, d19 // t1 870 vqsub.s16 d7, d23, d19 // t5 871 vqadd.s16 d8, d18, d22 // t2 872 vqsub.s16 d9, d18, d22 // t6 873 vqadd.s16 d18, d21, d17 // t3 874 vqsub.s16 d19, d21, d17 // t7 875 876 vmull_vmlal q8, d5, d7, d2[3], d2[2] 877 vmull_vmlsl q10, d5, d7, d2[2], d2[3] 878 vmull_vmlsl q11, d19, d9, d2[3], d2[2] 879 880 vqrshrn.s32 d5, q8, #12 // t4a 881 vqrshrn.s32 d7, q10, #12 // t5a 882 883 vmull_vmlal q8, d19, d9, d2[2], d2[3] 884 885 vqrshrn.s32 d9, q11, #12 // t6a 886 vqrshrn.s32 d19, q8, #12 // t7a 887 888 vqadd.s16 \r0, d4, d8 // out0 889 vqsub.s16 d4, d4, d8 // t2 890 vqadd.s16 \r7, d6, d18 // out7 891 vqsub.s16 d6, d6, d18 // t3 892 vqneg.s16 \r7, \r7 // out7 893 894 vqadd.s16 \r1, d5, d9 // out1 895 vqsub.s16 d5, d5, d9 // t6 896 vqadd.s16 \r6, d7, d19 // out6 897 vqsub.s16 d7, d7, d19 // t7 898 vqneg.s16 \r1, \r1 // out1 899 900 vmull_vmlal q9, d4, d6, d2[0], d2[0] // -> out3 (d19 or d20) 901 vmull_vmlsl q4, d4, d6, d2[0], d2[0] // -> out4 (d20 or d19) 902 vmull_vmlsl q10, d5, d7, d2[0], d2[0] // -> out5 (d21 or d18) 903 vqrshrn.s32 d4, q9, #12 // out3 904 vmull_vmlal q9, d5, d7, d2[0], d2[0] // -> out2 (d18 or d21) 905 vqrshrn.s32 d5, q10, #12 // out5 906 vqrshrn.s32 \r2, q9, #12 // out2 (d18 or d21) 907 vqrshrn.s32 \r4, q4, #12 // out4 (d20 or d19) 908 909 vqneg.s16 \r3, d4 // out3 910 vqneg.s16 \r5, d5 // out5 911.endm 912 913function inv_adst_8h_x8_neon, export=1 914 iadst_8h_x8 q8, q9, q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 915 bx lr 916endfunc 917 918function inv_flipadst_8h_x8_neon, export=1 919 iadst_8h_x8 q15, q14, q13, q12, q11, q10, q9, q8, d30, d31, d28, d29, d26, d27, d24, d25, d22, d23, d20, d21, d18, d19, d16, d17 920 bx lr 921endfunc 922 923function inv_adst_4h_x8_neon, export=1 924 iadst_4h_x8 d16, d17, d18, d19, d20, d21, d22, d23 925 bx lr 926endfunc 927 928function inv_flipadst_4h_x8_neon, export=1 929 iadst_4h_x8 d23, d22, d21, d20, d19, d18, d17, d16 930 bx lr 931endfunc 932 933function inv_identity_8h_x8_neon, export=1 934 vqshl.s16 q8, q8, #1 935 vqshl.s16 q9, q9, #1 936 vqshl.s16 q10, q10, #1 937 vqshl.s16 q11, q11, #1 938 vqshl.s16 q12, q12, #1 939 vqshl.s16 q13, q13, #1 940 vqshl.s16 q14, q14, #1 941 vqshl.s16 q15, q15, #1 942 bx lr 943endfunc 944 945function inv_identity_4h_x8_neon, export=1 946 vqshl.s16 q8, q8, #1 947 vqshl.s16 q9, q9, #1 948 vqshl.s16 q10, q10, #1 949 vqshl.s16 q11, q11, #1 950 bx lr 951endfunc 952 953.macro def_fn_8x8_base variant 954function inv_txfm_\variant\()add_8x8_neon 955 vmov.i16 q0, #0 956 vmov.i16 q1, #0 957 vld1.16 {q8, q9}, [r2, :128] 958 vst1.16 {q0, q1}, [r2, :128]! 959 vld1.16 {q10, q11}, [r2, :128] 960 vst1.16 {q0, q1}, [r2, :128]! 961 vld1.16 {q12, q13}, [r2, :128] 962 vst1.16 {q0, q1}, [r2, :128]! 963 vld1.16 {q14, q15}, [r2, :128] 964 vst1.16 {q0, q1}, [r2, :128] 965 966.ifc \variant, identity_ 967 // The identity shl #1 and downshift srshr #1 cancel out 968 969 b L(itx_8x8_epilog) 970.else 971 blx r4 972 973 vrshr.s16 q8, q8, #1 974 vrshr.s16 q9, q9, #1 975 vrshr.s16 q10, q10, #1 976 vrshr.s16 q11, q11, #1 977 vrshr.s16 q12, q12, #1 978 vrshr.s16 q13, q13, #1 979 vrshr.s16 q14, q14, #1 980 vrshr.s16 q15, q15, #1 981 982L(itx_8x8_epilog): 983 transpose_8x8h q8, q9, q10, q11, q12, q13, q14, q15, d17, d19, d21, d23, d24, d26, d28, d30 984 985 blx r5 986 987 load_add_store_8x8 r0, r7 988 vpop {q4-q7} 989 pop {r4-r5,r7,pc} 990.endif 991endfunc 992.endm 993 994def_fn_8x8_base identity_ 995def_fn_8x8_base 996 997.macro def_fn_8x8 txfm1, txfm2 998function inv_txfm_add_\txfm1\()_\txfm2\()_8x8_8bpc_neon, export=1 999.ifc \txfm1\()_\txfm2, dct_dct 1000 idct_dc 8, 8, 1 1001.endif 1002 push {r4-r5,r7,lr} 1003 vpush {q4-q7} 1004 movrel_local r5, inv_\txfm2\()_8h_x8_neon 1005.ifc \txfm1, identity 1006 b inv_txfm_identity_add_8x8_neon 1007.else 1008 movrel_local r4, inv_\txfm1\()_8h_x8_neon 1009 b inv_txfm_add_8x8_neon 1010.endif 1011endfunc 1012.endm 1013 1014def_fn_8x8 dct, dct 1015def_fn_8x8 identity, identity 1016def_fn_8x8 dct, adst 1017def_fn_8x8 dct, flipadst 1018def_fn_8x8 dct, identity 1019def_fn_8x8 adst, dct 1020def_fn_8x8 adst, adst 1021def_fn_8x8 adst, flipadst 1022def_fn_8x8 flipadst, dct 1023def_fn_8x8 flipadst, adst 1024def_fn_8x8 flipadst, flipadst 1025def_fn_8x8 identity, dct 1026def_fn_8x8 adst, identity 1027def_fn_8x8 flipadst, identity 1028def_fn_8x8 identity, adst 1029def_fn_8x8 identity, flipadst 1030 1031function inv_txfm_add_8x4_neon 1032 vmov.i16 q14, #0 1033 vmov.i16 q15, #0 1034 movw r12, #2896*8 1035 vdup.16 d0, r12 1036 vld1.16 {d16, d17, d18, d19}, [r2, :128] 1037 vst1.16 {q14, q15}, [r2, :128]! 1038 vld1.16 {d20, d21, d22, d23}, [r2, :128] 1039 vst1.16 {q14, q15}, [r2, :128] 1040 1041 scale_input d0[0], q8, q9, q10, q11 1042 1043 blx r4 1044 1045 transpose_4x4h q8, q9, d16, d17, d18, d19 1046 transpose_4x4h q10, q11, d20, d21, d22, d23 1047 vswp d17, d20 1048 vswp d19, d21 1049 vswp d18, d20 1050 vswp d21, d22 1051 1052 blx r5 1053 1054 load_add_store_8x4 r0, r7 1055 vpop {q4-q7} 1056 pop {r4-r5,r7,pc} 1057endfunc 1058 1059function inv_txfm_add_4x8_neon 1060 vmov.i16 q14, #0 1061 vmov.i16 q15, #0 1062 movw r12, #2896*8 1063 vdup.16 d0, r12 1064 vld1.16 {q8, q9}, [r2, :128] 1065 vst1.16 {q14, q15}, [r2, :128]! 1066 vld1.16 {q10, q11}, [r2, :128] 1067 vst1.16 {q14, q15}, [r2, :128] 1068 1069 scale_input d0[0], q8, q9, q10, q11 1070 1071 blx r4 1072 1073 transpose_4x8h q8, q9, q10, q11 1074 vswp d17, d20 1075 vswp d19, d21 1076 vswp d17, d18 1077 vswp d19, d22 1078 1079 blx r5 1080 1081 load_add_store_4x8 r0, r7 1082 vpop {q4-q7} 1083 pop {r4-r5,r7,pc} 1084endfunc 1085 1086.macro def_fn_48 w, h, txfm1, txfm2 1087function inv_txfm_add_\txfm1\()_\txfm2\()_\w\()x\h\()_8bpc_neon, export=1 1088.ifc \txfm1\()_\txfm2, dct_dct 1089 idct_dc \w, \h, 0 1090.endif 1091 push {r4-r5,r7,lr} 1092 vpush {q4-q7} 1093 movrel_local r4, inv_\txfm1\()_\h\()h_x\w\()_neon 1094 movrel_local r5, inv_\txfm2\()_\w\()h_x\h\()_neon 1095 b inv_txfm_add_\w\()x\h\()_neon 1096endfunc 1097.endm 1098 1099.macro def_fns_48 w, h 1100def_fn_48 \w, \h, dct, dct 1101def_fn_48 \w, \h, identity, identity 1102def_fn_48 \w, \h, dct, adst 1103def_fn_48 \w, \h, dct, flipadst 1104def_fn_48 \w, \h, dct, identity 1105def_fn_48 \w, \h, adst, dct 1106def_fn_48 \w, \h, adst, adst 1107def_fn_48 \w, \h, adst, flipadst 1108def_fn_48 \w, \h, flipadst, dct 1109def_fn_48 \w, \h, flipadst, adst 1110def_fn_48 \w, \h, flipadst, flipadst 1111def_fn_48 \w, \h, identity, dct 1112def_fn_48 \w, \h, adst, identity 1113def_fn_48 \w, \h, flipadst, identity 1114def_fn_48 \w, \h, identity, adst 1115def_fn_48 \w, \h, identity, flipadst 1116.endm 1117 1118def_fns_48 4, 8 1119def_fns_48 8, 4 1120 1121function inv_dct_4h_x16_neon, export=1 1122 movrel_local r12, idct_coeffs 1123 vld1.16 {q0, q1}, [r12, :128] 1124 1125 vmull_vmlsl q2, d17, d31, d2[0], d2[1] // -> t8a 1126 vmull_vmlal q3, d17, d31, d2[1], d2[0] // -> t15a 1127 vmull_vmlsl q4, d25, d23, d2[2], d2[3] // -> t9a 1128 vqrshrn.s32 d17, q2, #12 // t8a 1129 vqrshrn.s32 d31, q3, #12 // t15a 1130 vmull_vmlal q2, d25, d23, d2[3], d2[2] // -> t14a 1131 vmull_vmlsl q3, d21, d27, d3[0], d3[1] // -> t10a 1132 vqrshrn.s32 d23, q4, #12 // t9a 1133 vqrshrn.s32 d25, q2, #12 // t14a 1134 vmull_vmlal q4, d21, d27, d3[1], d3[0] // -> t13a 1135 vmull_vmlsl q2, d29, d19, d3[2], d3[3] // -> t11a 1136 vqrshrn.s32 d21, q3, #12 // t10a 1137 vqrshrn.s32 d27, q4, #12 // t13a 1138 vmull_vmlal q3, d29, d19, d3[3], d3[2] // -> t12a 1139 vqrshrn.s32 d19, q2, #12 // t11a 1140 vqrshrn.s32 d29, q3, #12 // t12a 1141 1142 idct_4h_x8 d16, d18, d20, d22, d24, d26, d28, d30 1143 1144 vqsub.s16 d4, d17, d23 // t9 1145 vqadd.s16 d17, d17, d23 // t8 1146 vqsub.s16 d5, d31, d25 // t14 1147 vqadd.s16 d31, d31, d25 // t15 1148 vqsub.s16 d23, d19, d21 // t10 1149 vqadd.s16 d19, d19, d21 // t11 1150 vqadd.s16 d25, d29, d27 // t12 1151 vqsub.s16 d29, d29, d27 // t13 1152 1153 vmull_vmlsl q3, d5, d4, d0[2], d0[3] // -> t9a 1154 vmull_vmlal q4, d5, d4, d0[3], d0[2] // -> t14a 1155 vqrshrn.s32 d21, q3, #12 // t9a 1156 vqrshrn.s32 d27, q4, #12 // t14a 1157 1158 vmull_vmlsl q3, d29, d23, d0[2], d0[3] // -> t13a 1159 vmull_vmlal q4, d29, d23, d0[3], d0[2] // -> t10a 1160 vqrshrn.s32 d29, q3, #12 // t13a 1161 vneg.s32 q4, q4 1162 vqrshrn.s32 d23, q4, #12 // t10a 1163 1164 vqsub.s16 d4, d17, d19 // t11a 1165 vqadd.s16 d17, d17, d19 // t8a 1166 vqsub.s16 d5, d31, d25 // t12a 1167 vqadd.s16 d31, d31, d25 // t15a 1168 vqadd.s16 d19, d21, d23 // t9 1169 vqsub.s16 d21, d21, d23 // t10 1170 vqsub.s16 d25, d27, d29 // t13 1171 vqadd.s16 d27, d27, d29 // t14 1172 1173 vmull_vmlsl q3, d5, d4, d0[0], d0[0] // -> t11 1174 vmull_vmlal q4, d5, d4, d0[0], d0[0] // -> t12 1175 vmull_vmlsl q2, d25, d21, d0[0], d0[0] // -> t10a 1176 1177 vqrshrn.s32 d6, q3, #12 // t11 1178 vqrshrn.s32 d7, q4, #12 // t12 1179 vmull_vmlal q4, d25, d21, d0[0], d0[0] // -> t13a 1180 vqrshrn.s32 d4, q2, #12 // t10a 1181 vqrshrn.s32 d5, q4, #12 // t13a 1182 1183 vqadd.s16 d8, d16, d31 // out0 1184 vqsub.s16 d31, d16, d31 // out15 1185 vmov d16, d8 1186 vqadd.s16 d23, d30, d17 // out7 1187 vqsub.s16 d9, d30, d17 // out8 1188 vqadd.s16 d17, d18, d27 // out1 1189 vqsub.s16 d30, d18, d27 // out14 1190 vqadd.s16 d18, d20, d5 // out2 1191 vqsub.s16 d29, d20, d5 // out13 1192 vqadd.s16 d5, d28, d19 // out6 1193 vqsub.s16 d25, d28, d19 // out9 1194 vqadd.s16 d19, d22, d7 // out3 1195 vqsub.s16 d28, d22, d7 // out12 1196 vqadd.s16 d20, d24, d6 // out4 1197 vqsub.s16 d27, d24, d6 // out11 1198 vqadd.s16 d21, d26, d4 // out5 1199 vqsub.s16 d26, d26, d4 // out10 1200 vmov d24, d9 1201 vmov d22, d5 1202 1203 bx lr 1204endfunc 1205 1206.macro iadst_16 o0, o1, o2, o3, o4, o5, o6, o7, o8, o9, o10, o11, o12, o13, o14, o15 1207 movrel_local r12, iadst16_coeffs 1208 vld1.16 {q0, q1}, [r12, :128] 1209 movrel_local r12, idct_coeffs 1210 1211 vmull_vmlal q2, d31, d16, d0[0], d0[1] // -> t0 1212 vmull_vmlsl q3, d31, d16, d0[1], d0[0] // -> t1 1213 vmull_vmlal q4, d29, d18, d0[2], d0[3] // -> t2 1214 vqrshrn.s32 d16, q2, #12 // t0 1215 vqrshrn.s32 d31, q3, #12 // t1 1216 vmull_vmlsl q2, d29, d18, d0[3], d0[2] // -> t3 1217 vmull_vmlal q3, d27, d20, d1[0], d1[1] // -> t4 1218 vqrshrn.s32 d18, q4, #12 // t2 1219 vqrshrn.s32 d29, q2, #12 // t3 1220 vmull_vmlsl q4, d27, d20, d1[1], d1[0] // -> t5 1221 vmull_vmlal q2, d25, d22, d1[2], d1[3] // -> t6 1222 vqrshrn.s32 d20, q3, #12 // t4 1223 vqrshrn.s32 d27, q4, #12 // t5 1224 vmull_vmlsl q3, d25, d22, d1[3], d1[2] // -> t7 1225 vmull_vmlal q4, d23, d24, d2[0], d2[1] // -> t8 1226 vqrshrn.s32 d22, q2, #12 // t6 1227 vqrshrn.s32 d25, q3, #12 // t7 1228 vmull_vmlsl q2, d23, d24, d2[1], d2[0] // -> t9 1229 vmull_vmlal q3, d21, d26, d2[2], d2[3] // -> t10 1230 vqrshrn.s32 d23, q4, #12 // t8 1231 vqrshrn.s32 d24, q2, #12 // t9 1232 vmull_vmlsl q4, d21, d26, d2[3], d2[2] // -> t11 1233 vmull_vmlal q2, d19, d28, d3[0], d3[1] // -> t12 1234 vqrshrn.s32 d21, q3, #12 // t10 1235 vqrshrn.s32 d26, q4, #12 // t11 1236 vmull_vmlsl q3, d19, d28, d3[1], d3[0] // -> t13 1237 vmull_vmlal q4, d17, d30, d3[2], d3[3] // -> t14 1238 vqrshrn.s32 d19, q2, #12 // t12 1239 vqrshrn.s32 d28, q3, #12 // t13 1240 vmull_vmlsl q2, d17, d30, d3[3], d3[2] // -> t15 1241 vqrshrn.s32 d17, q4, #12 // t14 1242 vqrshrn.s32 d30, q2, #12 // t15 1243 1244 vld1.16 {q0}, [r12, :128] 1245 1246 vqsub.s16 d2, d16, d23 // t8a 1247 vqadd.s16 d16, d16, d23 // t0a 1248 vqsub.s16 d3, d31, d24 // t9a 1249 vqadd.s16 d31, d31, d24 // t1a 1250 vqadd.s16 d23, d18, d21 // t2a 1251 vqsub.s16 d18, d18, d21 // t10a 1252 vqadd.s16 d24, d29, d26 // t3a 1253 vqsub.s16 d29, d29, d26 // t11a 1254 vqadd.s16 d21, d20, d19 // t4a 1255 vqsub.s16 d20, d20, d19 // t12a 1256 vqadd.s16 d26, d27, d28 // t5a 1257 vqsub.s16 d27, d27, d28 // t13a 1258 vqadd.s16 d19, d22, d17 // t6a 1259 vqsub.s16 d22, d22, d17 // t14a 1260 vqadd.s16 d28, d25, d30 // t7a 1261 vqsub.s16 d25, d25, d30 // t15a 1262 1263 vmull_vmlal q2, d2, d3, d1[1], d1[0] // -> t8 1264 vmull_vmlsl q3, d2, d3, d1[0], d1[1] // -> t9 1265 vmull_vmlal q4, d18, d29, d1[3], d1[2] // -> t10 1266 vqrshrn.s32 d17, q2, #12 // t8 1267 vqrshrn.s32 d30, q3, #12 // t9 1268 vmull_vmlsl q2, d18, d29, d1[2], d1[3] // -> t11 1269 vmull_vmlsl q3, d27, d20, d1[1], d1[0] // -> t12 1270 vqrshrn.s32 d18, q4, #12 // t10 1271 vqrshrn.s32 d29, q2, #12 // t11 1272 vmull_vmlal q4, d27, d20, d1[0], d1[1] // -> t13 1273 vmull_vmlsl q2, d25, d22, d1[3], d1[2] // -> t14 1274 vqrshrn.s32 d27, q3, #12 // t12 1275 vqrshrn.s32 d20, q4, #12 // t13 1276 vmull_vmlal q3, d25, d22, d1[2], d1[3] // -> t15 1277 vqrshrn.s32 d25, q2, #12 // t14 1278 vqrshrn.s32 d22, q3, #12 // t15 1279 1280 vqsub.s16 d2, d16, d21 // t4 1281 vqadd.s16 d16, d16, d21 // t0 1282 vqsub.s16 d3, d31, d26 // t5 1283 vqadd.s16 d31, d31, d26 // t1 1284 vqadd.s16 d21, d23, d19 // t2 1285 vqsub.s16 d23, d23, d19 // t6 1286 vqadd.s16 d26, d24, d28 // t3 1287 vqsub.s16 d24, d24, d28 // t7 1288 vqadd.s16 d19, d17, d27 // t8a 1289 vqsub.s16 d17, d17, d27 // t12a 1290 vqadd.s16 d28, d30, d20 // t9a 1291 vqsub.s16 d30, d30, d20 // t13a 1292 vqadd.s16 d27, d18, d25 // t10a 1293 vqsub.s16 d18, d18, d25 // t14a 1294 vqadd.s16 d20, d29, d22 // t11a 1295 vqsub.s16 d29, d29, d22 // t15a 1296 1297 vmull_vmlal q2, d2, d3, d0[3], d0[2] // -> t4a 1298 vmull_vmlsl q3, d2, d3, d0[2], d0[3] // -> t5a 1299 vmull_vmlsl q4, d24, d23, d0[3], d0[2] // -> t6a 1300 vqrshrn.s32 d22, q2, #12 // t4a 1301 vqrshrn.s32 d25, q3, #12 // t5a 1302 vmull_vmlal q2, d24, d23, d0[2], d0[3] // -> t7a 1303 vmull_vmlal q3, d17, d30, d0[3], d0[2] // -> t12 1304 vqrshrn.s32 d24, q4, #12 // t6a 1305 vqrshrn.s32 d23, q2, #12 // t7a 1306 vmull_vmlsl q4, d17, d30, d0[2], d0[3] // -> t13 1307 vmull_vmlsl q2, d29, d18, d0[3], d0[2] // -> t14 1308 vqrshrn.s32 d17, q3, #12 // t12 1309 vmull_vmlal q3, d29, d18, d0[2], d0[3] // -> t15 1310 vqrshrn.s32 d29, q4, #12 // t13 1311 vqrshrn.s32 d30, q2, #12 // t14 1312 vqrshrn.s32 d18, q3, #12 // t15 1313 1314 vqsub.s16 d2, d16, d21 // t2a 1315.ifc \o0, d16 1316 vqadd.s16 \o0, d16, d21 // out0 1317 vqsub.s16 d21, d31, d26 // t3a 1318 vqadd.s16 \o15,d31, d26 // out15 1319.else 1320 vqadd.s16 d4, d16, d21 // out0 1321 vqsub.s16 d21, d31, d26 // t3a 1322 vqadd.s16 \o15,d31, d26 // out15 1323 vmov \o0, d4 1324.endif 1325 vqneg.s16 \o15, \o15 // out15 1326 1327 vqsub.s16 d3, d29, d18 // t15a 1328 vqadd.s16 \o13,d29, d18 // out13 1329 vqadd.s16 \o2, d17, d30 // out2 1330 vqsub.s16 d26, d17, d30 // t14a 1331 vqneg.s16 \o13,\o13 // out13 1332 1333 vqadd.s16 \o1, d19, d27 // out1 1334 vqsub.s16 d27, d19, d27 // t10 1335 vqadd.s16 \o14,d28, d20 // out14 1336 vqsub.s16 d20, d28, d20 // t11 1337 vqneg.s16 \o1, \o1 // out1 1338 1339 vqadd.s16 \o3, d22, d24 // out3 1340 vqsub.s16 d22, d22, d24 // t6 1341 vqadd.s16 \o12,d25, d23 // out12 1342 vqsub.s16 d23, d25, d23 // t7 1343 vqneg.s16 \o3, \o3 // out3 1344 1345 vmull_vmlsl q12, d2, d21, d0[0], d0[0] // -> out8 (d24 or d23) 1346 vmull_vmlal q2, d2, d21, d0[0], d0[0] // -> out7 (d23 or d24) 1347 vmull_vmlal q3, d26, d3, d0[0], d0[0] // -> out5 (d21 or d26) 1348 1349 vqrshrn.s32 d24, q12, #12 // out8 1350 vqrshrn.s32 d4, q2, #12 // out7 1351 vqrshrn.s32 d5, q3, #12 // out5 1352 vmull_vmlsl q4, d26, d3, d0[0], d0[0] // -> out10 (d26 or d21) 1353 vmull_vmlal q1, d22, d23, d0[0], d0[0] // -> out4 (d20 or d27) 1354 vqrshrn.s32 d26, q4, #12 // out10 1355 1356 vmull_vmlsl q4, d22, d23, d0[0], d0[0] // -> out11 (d27 or d20) 1357 vmull_vmlal q11, d27, d20, d0[0], d0[0] // -> out6 (d22 or d25) 1358 vmull_vmlsl q3, d27, d20, d0[0], d0[0] // -> out9 (d25 or d22) 1359 1360 vqrshrn.s32 \o4, q1, #12 // out4 1361 vqrshrn.s32 d7, q3, #12 // out9 1362 vqrshrn.s32 d6, q4, #12 // out11 1363 vqrshrn.s32 \o6, q11, #12 // out6 1364 1365.ifc \o8, d23 1366 vmov \o8, d24 1367 vmov \o10,d26 1368.endif 1369 1370 vqneg.s16 \o7, d4 // out7 1371 vqneg.s16 \o5, d5 // out5 1372 vqneg.s16 \o11,d6 // out11 1373 vqneg.s16 \o9, d7 // out9 1374.endm 1375 1376function inv_adst_4h_x16_neon, export=1 1377 iadst_16 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 1378 bx lr 1379endfunc 1380 1381function inv_flipadst_4h_x16_neon, export=1 1382 iadst_16 d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16 1383 bx lr 1384endfunc 1385 1386function inv_identity_4h_x16_neon, export=1 1387 movw r12, #2*(5793-4096)*8 1388 vdup.16 d0, r12 1389.irp i, q8, q9, q10, q11, q12, q13, q14, q15 1390 vqrdmulh.s16 q1, \i, d0[0] 1391 vqadd.s16 \i, \i, \i 1392 vqadd.s16 \i, \i, q1 1393.endr 1394 bx lr 1395endfunc 1396 1397.macro identity_4x16_shift2 c 1398.irp i, q8, q9, q10, q11, q12, q13, q14, q15 1399 vqrdmulh.s16 q2, \i, \c 1400 vshr.s16 q2, q2, #1 1401 vrhadd.s16 \i, \i, q2 1402.endr 1403.endm 1404 1405.macro identity_4x16_shift1 c 1406.irp i, q8, q9, q10, q11, q12, q13, q14, q15 1407 vqrdmulh.s16 q2, \i, \c 1408 vrshr.s16 q2, q2, #1 1409 vqadd.s16 \i, \i, q2 1410.endr 1411.endm 1412 1413.macro identity_8x8_shift1 c 1414 identity_4x16_shift1 \c 1415.endm 1416 1417.macro identity_8x8 c 1418.irp i, q8, q9, q10, q11, q12, q13, q14, q15 1419 vqrdmulh.s16 q2, \i, \c 1420 vqadd.s16 \i, \i, \i 1421 vqadd.s16 \i, \i, q2 1422.endr 1423.endm 1424 1425.macro def_horz_16 scale=0, identity=0, shift=2, suffix 1426function inv_txfm_horz\suffix\()_16x4_neon 1427 push {lr} 1428 vmov.i16 d7, #0 1429.if \identity 1430 movw r12, #2*(5793-4096)*8 1431 vdup.16 d0, r12 1432.endif 1433.if \scale 1434 movw r12, #2896*8 1435 vdup.16 d1, r12 1436.endif 1437.irp i, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 1438 vld1.16 {\i}, [r7, :64] 1439 vst1.16 {d7}, [r7, :64], r8 1440.endr 1441.if \scale 1442 scale_input d1[0], q8, q9, q10, q11, q12, q13, q14, q15 1443.endif 1444.if \identity 1445.if \shift == -2 1446 identity_4x16_shift2 d0[0] 1447.else 1448 identity_4x16_shift1 d0[0] 1449.endif 1450 b L(horz_16x4_epilog) 1451.else 1452 blx r4 1453.irp i, q8, q9, q10, q11, q12, q13, q14, q15 1454 vrshr.s16 \i, \i, #\shift 1455.endr 1456.if \shift == 1 1457 b L(horz_16x4_epilog) 1458.else 1459L(horz_16x4_epilog): 1460 transpose_4x4h q8, q9, d16, d17, d18, d19 1461 transpose_4x4h q10, q11, d20, d21, d22, d23 1462 transpose_4x4h q12, q13, d24, d25, d26, d27 1463 transpose_4x4h q14, q15, d28, d29, d30, d31 1464 1465.irp i, d16, d20, d24, d28, d17, d21, d25, d29, d18, d22, d26, d30, d19, d23, d27, d31 1466 vst1.16 {\i}, [r6, :64]! 1467.endr 1468 1469 pop {pc} 1470.endif 1471.endif 1472endfunc 1473.endm 1474 1475def_horz_16 scale=1, identity=1, shift=-1, suffix=_scale_identity 1476def_horz_16 scale=0, identity=1, shift=-2, suffix=_identity 1477def_horz_16 scale=1, identity=0, shift=1, suffix=_scale 1478def_horz_16 scale=0, identity=0, shift=2 1479 1480function inv_txfm_add_vert_4x16_neon 1481 push {lr} 1482.irp i, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 1483 vld1.16 {\i}, [r7, :64], r8 1484.endr 1485 blx r5 1486 load_add_store_4x16 r6, r7 1487 pop {pc} 1488endfunc 1489 1490function inv_txfm_add_16x16_neon 1491 sub_sp_align 512 1492 ldrh r11, [r10], #2 1493.irp i, 0, 4, 8, 12 1494 add r6, sp, #(\i*16*2) 1495.if \i > 0 1496 mov r8, #(16 - \i) 1497 cmp r3, r11 1498 blt 1f 1499.if \i < 12 1500 ldrh r11, [r10], #2 1501.endif 1502.endif 1503 add r7, r2, #(\i*2) 1504 mov r8, #16*2 1505 blx r9 1506.endr 1507 b 3f 15081: 1509 vmov.i16 q2, #0 1510 vmov.i16 q3, #0 15112: 1512 subs r8, r8, #4 1513.rept 4 1514 vst1.16 {q2, q3}, [r6, :128]! 1515.endr 1516 bgt 2b 15173: 1518.irp i, 0, 4, 8, 12 1519 add r6, r0, #(\i) 1520 add r7, sp, #(\i*2) 1521 mov r8, #32 1522 bl inv_txfm_add_vert_4x16_neon 1523.endr 1524 1525 add_sp_align 512 1526 vpop {q4} 1527 pop {r4-r11,pc} 1528endfunc 1529 1530const eob_16x16 1531 .short 10, 36, 78, 256 1532endconst 1533 1534const eob_16x16_identity 1535 .short 4, 8, 12, 256 1536endconst 1537 1538.macro def_fn_16x16 txfm1, txfm2 1539function inv_txfm_add_\txfm1\()_\txfm2\()_16x16_8bpc_neon, export=1 1540.ifc \txfm1\()_\txfm2, dct_dct 1541 idct_dc 16, 16, 2 1542.endif 1543 push {r4-r11,lr} 1544 vpush {q4} 1545.ifc \txfm1, identity 1546 movrel_local r9, inv_txfm_horz_identity_16x4_neon 1547.else 1548 movrel_local r9, inv_txfm_horz_16x4_neon 1549 movrel_local r4, inv_\txfm1\()_4h_x16_neon 1550.endif 1551 movrel_local r5, inv_\txfm2\()_4h_x16_neon 1552.ifc \txfm1, identity 1553.ifc \txfm2, identity 1554 movrel_local r10, eob_16x16 1555.else 1556 movrel_local r10, eob_16x16_identity 1557.endif 1558.else 1559.ifc \txfm2, identity 1560 movrel_local r10, eob_16x16_identity 1561.else 1562 movrel_local r10, eob_16x16 1563.endif 1564.endif 1565 b inv_txfm_add_16x16_neon 1566endfunc 1567.endm 1568 1569def_fn_16x16 dct, dct 1570def_fn_16x16 identity, identity 1571def_fn_16x16 dct, adst 1572def_fn_16x16 dct, flipadst 1573def_fn_16x16 dct, identity 1574def_fn_16x16 adst, dct 1575def_fn_16x16 adst, adst 1576def_fn_16x16 adst, flipadst 1577def_fn_16x16 flipadst, dct 1578def_fn_16x16 flipadst, adst 1579def_fn_16x16 flipadst, flipadst 1580def_fn_16x16 identity, dct 1581 1582.macro def_fn_416_base variant 1583function inv_txfm_\variant\()add_16x4_neon 1584 1585.ifc \variant, identity_ 1586 vmov.i16 d4, #0 1587.irp i, d16, d18, d20, d22 1588 vld1.16 {\i}, [r2, :64] 1589 vst1.16 {d4}, [r2, :64]! 1590.endr 1591.irp i, d17, d19, d21, d23 1592 vld1.16 {\i}, [r2, :64] 1593 vst1.16 {d4}, [r2, :64]! 1594.endr 1595 movw r12, #2*(5793-4096)*8 1596 vdup.16 d0, r12 1597.irp i, d24, d26, d28, d30 1598 vld1.16 {\i}, [r2, :64] 1599 vst1.16 {d4}, [r2, :64]! 1600.endr 1601.irp i, d25, d27, d29, d31 1602 vld1.16 {\i}, [r2, :64] 1603 vst1.16 {d4}, [r2, :64]! 1604.endr 1605 1606 identity_4x16_shift1 d0[0] 1607 1608 b L(itx_16x4_epilog) 1609.else 1610 vmov.i16 q2, #0 1611 vmov.i16 q3, #0 1612 vld1.16 {d16, d17, d18, d19}, [r2, :128] 1613 vst1.16 {q2, q3}, [r2, :128]! 1614 vld1.16 {d20, d21, d22, d23}, [r2, :128] 1615 vst1.16 {q2, q3}, [r2, :128]! 1616 vld1.16 {d24, d25, d26, d27}, [r2, :128] 1617 vst1.16 {q2, q3}, [r2, :128]! 1618 vld1.16 {d28, d29, d30, d31}, [r2, :128] 1619 vst1.16 {q2, q3}, [r2, :128]! 1620 1621 blx r4 1622 1623 vswp d17, d20 1624 vswp d19, d22 1625 vswp d18, d20 1626 vswp d19, d21 1627 vswp d25, d28 1628 vswp d27, d30 1629 vswp d26, d28 1630 vswp d27, d29 1631.irp i, q8, q9, q10, q11, q12, q13, q14, q15 1632 vrshr.s16 \i, \i, #1 1633.endr 1634 1635L(itx_16x4_epilog): 1636 transpose_4x8h q8, q9, q10, q11 1637 blx r5 1638 mov r6, r0 1639 load_add_store_8x4 r6, r7 1640 1641 vmov q8, q12 1642 vmov q9, q13 1643 vmov q10, q14 1644 vmov q11, q15 1645 1646 transpose_4x8h q8, q9, q10, q11 1647 blx r5 1648 add r6, r0, #8 1649 load_add_store_8x4 r6, r7 1650 1651 vpop {q4-q7} 1652 pop {r4-r11,pc} 1653.endif 1654endfunc 1655 1656function inv_txfm_\variant\()add_4x16_neon 1657 vmov.i16 q2, #0 1658 1659 mov r11, #32 1660 cmp r3, r10 1661 blt 1f 1662 1663 add r6, r2, #16 1664.ifc \variant, identity_ 1665.irp i, q12, q13, q14, q15 1666 vld1.16 {\i}, [r6, :128] 1667 vst1.16 {q2}, [r6, :128], r11 1668.endr 1669 movw r12, #(5793-4096)*8 1670 vdup.16 d0, r12 1671 identity_8x4_shift1 q12, q13, q14, q15, d0[0] 1672.else 1673.irp i, q8, q9, q10, q11 1674 vld1.16 {\i}, [r6, :128] 1675 vst1.16 {q2}, [r6, :128], r11 1676.endr 1677 blx r4 1678 vrshr.s16 q12, q8, #1 1679 vrshr.s16 q13, q9, #1 1680 vrshr.s16 q14, q10, #1 1681 vrshr.s16 q15, q11, #1 1682.endif 1683 transpose_4x8h q12, q13, q14, q15 1684 vswp d27, d29 1685 vswp d26, d28 1686 vswp d27, d30 1687 vswp d25, d28 1688 1689 b 2f 16901: 1691.irp i, q12, q13, q14, q15 1692 vmov.i16 \i, #0 1693.endr 16942: 1695 vmov.i16 q2, #0 1696.irp i, q8, q9, q10, q11 1697 vld1.16 {\i}, [r2, :128] 1698 vst1.16 {q2}, [r2, :128], r11 1699.endr 1700.ifc \variant, identity_ 1701 movw r12, #(5793-4096)*8 1702 vdup.16 d0, r12 1703 identity_8x4_shift1 q8, q9, q10, q11, d0[0] 1704 1705 b L(itx_4x16_epilog) 1706.else 1707 blx r4 1708.irp i, q8, q9, q10, q11 1709 vrshr.s16 \i, \i, #1 1710.endr 1711L(itx_4x16_epilog): 1712 transpose_4x8h q8, q9, q10, q11 1713 vswp d19, d21 1714 vswp d18, d20 1715 vswp d19, d22 1716 vswp d17, d20 1717 1718 blx r5 1719 1720 load_add_store_4x16 r0, r6 1721 1722 vpop {q4-q7} 1723 pop {r4-r11,pc} 1724.endif 1725endfunc 1726.endm 1727 1728def_fn_416_base identity_ 1729def_fn_416_base 1730 1731.macro def_fn_416 w, h, txfm1, txfm2, eob_half 1732function inv_txfm_add_\txfm1\()_\txfm2\()_\w\()x\h\()_8bpc_neon, export=1 1733.ifc \txfm1\()_\txfm2, dct_dct 1734 idct_dc \w, \h, 1 1735.endif 1736 push {r4-r11,lr} 1737 vpush {q4-q7} 1738.if \w == 4 1739.ifnc \txfm1, identity 1740 movrel_local r4, inv_\txfm1\()_8h_x\w\()_neon 1741.endif 1742 movrel_local r5, inv_\txfm2\()_4h_x\h\()_neon 1743 mov r10, #\eob_half 1744.else 1745.ifnc \txfm1, identity 1746 movrel_local r4, inv_\txfm1\()_4h_x\w\()_neon 1747.endif 1748 movrel_local r5, inv_\txfm2\()_8h_x\h\()_neon 1749.endif 1750.ifc \txfm1, identity 1751 b inv_txfm_identity_add_\w\()x\h\()_neon 1752.else 1753 b inv_txfm_add_\w\()x\h\()_neon 1754.endif 1755endfunc 1756.endm 1757 1758.macro def_fns_416 w, h 1759def_fn_416 \w, \h, dct, dct, 29 1760def_fn_416 \w, \h, identity, identity, 29 1761def_fn_416 \w, \h, dct, adst, 29 1762def_fn_416 \w, \h, dct, flipadst, 29 1763def_fn_416 \w, \h, dct, identity, 8 1764def_fn_416 \w, \h, adst, dct, 29 1765def_fn_416 \w, \h, adst, adst, 29 1766def_fn_416 \w, \h, adst, flipadst, 29 1767def_fn_416 \w, \h, flipadst, dct, 29 1768def_fn_416 \w, \h, flipadst, adst, 29 1769def_fn_416 \w, \h, flipadst, flipadst, 29 1770def_fn_416 \w, \h, identity, dct, 32 1771def_fn_416 \w, \h, adst, identity, 8 1772def_fn_416 \w, \h, flipadst, identity, 8 1773def_fn_416 \w, \h, identity, adst, 32 1774def_fn_416 \w, \h, identity, flipadst, 32 1775.endm 1776 1777def_fns_416 4, 16 1778def_fns_416 16, 4 1779 1780function inv_txfm_add_16x8_neon 1781 sub_sp_align 256 1782 1783.irp i, 0, 4 1784 add r6, sp, #(\i*16*2) 1785.if \i > 0 1786 cmp r3, r10 1787 blt 1f 1788.endif 1789 add r7, r2, #(\i*2) 1790 mov r8, #8*2 1791 blx r9 1792.endr 1793 b 2f 17941: 1795 vmov.i16 q2, #0 1796 vmov.i16 q3, #0 1797.rept 4 1798 vst1.16 {q2, q3}, [r6, :128]! 1799.endr 18002: 1801 1802.irp i, 0, 8 1803 add r7, sp, #(\i*2) 1804 mov r8, #32 1805.irp j, q8, q9, q10, q11, q12, q13, q14, q15 1806 vld1.16 {\j}, [r7, :128], r8 1807.endr 1808 blx r5 1809 1810 add r6, r0, #(\i) 1811 load_add_store_8x8 r6, r7 1812.endr 1813 1814 add_sp_align 256 1815 vpop {q4-q7} 1816 pop {r4-r11,pc} 1817endfunc 1818 1819.macro def_fn_816_base variant 1820function inv_txfm_\variant\()add_8x16_neon 1821 sub_sp_align 256 1822 1823.irp i, 0, 8 1824 add r6, sp, #(\i*8*2) 1825.if \i > 0 1826 cmp r3, r10 1827 blt 1f 1828.endif 1829 add r7, r2, #(\i*2) 1830 mov r8, #16*2 1831 1832 vmov.i16 q2, #0 1833 movw r12, #2896*8 1834 vdup.16 d0, r12 1835 1836.irp j, q8, q9, q10, q11, q12, q13, q14, q15 1837 vld1.16 {\j}, [r7, :128] 1838 vst1.16 {q2}, [r7, :128], r8 1839.endr 1840 scale_input d0[0], q8, q9, q10, q11, q12, q13, q14, q15 1841.ifc \variant, identity_ 1842 // The identity shl #1 and downshift vrshr #1 cancel out 1843.else 1844 blx r4 1845.irp j, q8, q9, q10, q11, q12, q13, q14, q15 1846 vrshr.s16 \j, \j, #1 1847.endr 1848.endif 1849 transpose_8x8h q8, q9, q10, q11, q12, q13, q14, q15, d17, d19, d21, d23, d24, d26, d28, d30 1850 vst1.16 {q8, q9}, [r6, :128]! 1851 vst1.16 {q10, q11}, [r6, :128]! 1852 vst1.16 {q12, q13}, [r6, :128]! 1853 vst1.16 {q14, q15}, [r6, :128]! 1854.endr 1855 b 2f 18561: 1857 vmov.i16 q2, #0 1858 vmov.i16 q3, #0 1859.rept 4 1860 vst1.16 {q2, q3}, [r6, :128]! 1861.endr 18622: 1863 1864.ifc \variant, identity_ 1865 b L(itx_8x16_epilog) 1866.else 1867L(itx_8x16_epilog): 1868.irp i, 0, 4 1869 add r6, r0, #(\i) 1870 add r7, sp, #(\i*2) 1871 mov r8, #16 1872 bl inv_txfm_add_vert_4x16_neon 1873.endr 1874 1875 add_sp_align 256 1876 vpop {q4-q7} 1877 pop {r4-r11,pc} 1878.endif 1879endfunc 1880.endm 1881 1882def_fn_816_base identity_ 1883def_fn_816_base 1884 1885/* Define symbols used in .if statement */ 1886.equ dct, 1 1887.equ identity, 2 1888.equ adst, 3 1889.equ flipadst, 4 1890 1891.macro def_fn_816 w, h, txfm1, txfm2, eob_8x8, eob_4x4 1892function inv_txfm_add_\txfm1\()_\txfm2\()_\w\()x\h\()_8bpc_neon, export=1 1893.ifc \txfm1\()_\txfm2, dct_dct 1894 idct_dc \w, \h, 1 1895.endif 1896 push {r4-r11,lr} 1897 vpush {q4-q7} 1898.if \w == 8 1899.ifnc \txfm1, identity 1900 movrel_local r4, inv_\txfm1\()_8h_x8_neon 1901.endif 1902 movrel_local r5, inv_\txfm2\()_4h_x16_neon 1903.else 1904.ifc \txfm1, identity 1905 movrel_local r9, inv_txfm_horz_scale_identity_16x4_neon 1906.else 1907 movrel_local r4, inv_\txfm1\()_4h_x16_neon 1908 movrel_local r9, inv_txfm_horz_scale_16x4_neon 1909.endif 1910 movrel_local r5, inv_\txfm2\()_8h_x8_neon 1911.endif 1912.if \w == 8 1913 mov r10, #\eob_8x8 1914.else 1915 mov r10, #\eob_4x4 1916.endif 1917.if \w == 8 && \txfm1 == identity 1918 b inv_txfm_identity_add_\w\()x\h\()_neon 1919.else 1920 b inv_txfm_add_\w\()x\h\()_neon 1921.endif 1922endfunc 1923.endm 1924 1925.macro def_fns_816 w, h 1926def_fn_816 \w, \h, dct, dct, 43, 10 1927def_fn_816 \w, \h, identity, identity, 43, 10 1928def_fn_816 \w, \h, dct, adst, 43, 10 1929def_fn_816 \w, \h, dct, flipadst, 43, 10 1930def_fn_816 \w, \h, dct, identity, 8, 4 1931def_fn_816 \w, \h, adst, dct, 43, 10 1932def_fn_816 \w, \h, adst, adst, 43, 10 1933def_fn_816 \w, \h, adst, flipadst, 43, 10 1934def_fn_816 \w, \h, flipadst, dct, 43, 10 1935def_fn_816 \w, \h, flipadst, adst, 43, 10 1936def_fn_816 \w, \h, flipadst, flipadst, 43, 10 1937def_fn_816 \w, \h, identity, dct, 64, 4 1938def_fn_816 \w, \h, adst, identity, 8, 4 1939def_fn_816 \w, \h, flipadst, identity, 8, 4 1940def_fn_816 \w, \h, identity, adst, 64, 4 1941def_fn_816 \w, \h, identity, flipadst, 64, 4 1942.endm 1943 1944def_fns_816 8, 16 1945def_fns_816 16, 8 1946 1947function inv_dct32_odd_4h_x16_neon, export=1 1948 movrel_local r12, idct_coeffs, 2*16 1949 vld1.16 {q0, q1}, [r12, :128] 1950 sub r12, r12, #2*16 1951 1952 vmull_vmlsl q2, d16, d31, d0[0], d0[1] // -> t16a 1953 vmull_vmlal q3, d16, d31, d0[1], d0[0] // -> t31a 1954 vmull_vmlsl q4, d24, d23, d0[2], d0[3] // -> t17a 1955 vqrshrn.s32 d16, q2, #12 // t16a 1956 vqrshrn.s32 d31, q3, #12 // t31a 1957 vmull_vmlal q2, d24, d23, d0[3], d0[2] // -> t30a 1958 vmull_vmlsl q3, d20, d27, d1[0], d1[1] // -> t18a 1959 vqrshrn.s32 d24, q4, #12 // t17a 1960 vqrshrn.s32 d23, q2, #12 // t30a 1961 vmull_vmlal q4, d20, d27, d1[1], d1[0] // -> t29a 1962 vmull_vmlsl q2, d28, d19, d1[2], d1[3] // -> t19a 1963 vqrshrn.s32 d20, q3, #12 // t18a 1964 vqrshrn.s32 d27, q4, #12 // t29a 1965 vmull_vmlal q3, d28, d19, d1[3], d1[2] // -> t28a 1966 vmull_vmlsl q4, d18, d29, d2[0], d2[1] // -> t20a 1967 vqrshrn.s32 d28, q2, #12 // t19a 1968 vqrshrn.s32 d19, q3, #12 // t28a 1969 vmull_vmlal q2, d18, d29, d2[1], d2[0] // -> t27a 1970 vmull_vmlsl q3, d26, d21, d2[2], d2[3] // -> t21a 1971 vqrshrn.s32 d18, q4, #12 // t20a 1972 vqrshrn.s32 d29, q2, #12 // t27a 1973 vmull_vmlal q4, d26, d21, d2[3], d2[2] // -> t26a 1974 vmull_vmlsl q2, d22, d25, d3[0], d3[1] // -> t22a 1975 vqrshrn.s32 d26, q3, #12 // t21a 1976 vqrshrn.s32 d21, q4, #12 // t26a 1977 vmull_vmlal q3, d22, d25, d3[1], d3[0] // -> t25a 1978 vmull_vmlsl q4, d30, d17, d3[2], d3[3] // -> t23a 1979 vqrshrn.s32 d22, q2, #12 // t22a 1980 vqrshrn.s32 d25, q3, #12 // t25a 1981 vmull_vmlal q2, d30, d17, d3[3], d3[2] // -> t24a 1982 vqrshrn.s32 d30, q4, #12 // t23a 1983 vqrshrn.s32 d17, q2, #12 // t24a 1984 1985 vld1.16 {q0}, [r12, :128] 1986 1987 vqsub.s16 d2, d16, d24 // t17 1988 vqadd.s16 d16, d16, d24 // t16 1989 vqsub.s16 d3, d31, d23 // t30 1990 vqadd.s16 d31, d31, d23 // t31 1991 vqsub.s16 d24, d28, d20 // t18 1992 vqadd.s16 d28, d28, d20 // t19 1993 vqadd.s16 d23, d18, d26 // t20 1994 vqsub.s16 d18, d18, d26 // t21 1995 vqsub.s16 d20, d30, d22 // t22 1996 vqadd.s16 d30, d30, d22 // t23 1997 vqadd.s16 d26, d17, d25 // t24 1998 vqsub.s16 d17, d17, d25 // t25 1999 vqsub.s16 d22, d29, d21 // t26 2000 vqadd.s16 d29, d29, d21 // t27 2001 vqadd.s16 d25, d19, d27 // t28 2002 vqsub.s16 d19, d19, d27 // t29 2003 2004 vmull_vmlsl q2, d3, d2, d1[0], d1[1] // -> t17a 2005 vmull_vmlal q3, d3, d2, d1[1], d1[0] // -> t30a 2006 vmull_vmlal q4, d19, d24, d1[1], d1[0] // -> t18a 2007 vqrshrn.s32 d21, q2, #12 // t17a 2008 vqrshrn.s32 d27, q3, #12 // t30a 2009 vneg.s32 q4, q4 // -> t18a 2010 vmull_vmlsl q1, d19, d24, d1[0], d1[1] // -> t29a 2011 vmull_vmlsl q2, d22, d18, d1[2], d1[3] // -> t21a 2012 vqrshrn.s32 d19, q4, #12 // t18a 2013 vqrshrn.s32 d24, q1, #12 // t29a 2014 vmull_vmlal q3, d22, d18, d1[3], d1[2] // -> t26a 2015 vmull_vmlal q4, d17, d20, d1[3], d1[2] // -> t22a 2016 vqrshrn.s32 d22, q2, #12 // t21a 2017 vqrshrn.s32 d18, q3, #12 // t26a 2018 vneg.s32 q4, q4 // -> t22a 2019 vmull_vmlsl q1, d17, d20, d1[2], d1[3] // -> t25a 2020 vqrshrn.s32 d17, q4, #12 // t22a 2021 vqrshrn.s32 d20, q1, #12 // t25a 2022 2023 vqsub.s16 d2, d27, d24 // t29 2024 vqadd.s16 d27, d27, d24 // t30 2025 vqsub.s16 d3, d21, d19 // t18 2026 vqadd.s16 d21, d21, d19 // t17 2027 vqsub.s16 d24, d16, d28 // t19a 2028 vqadd.s16 d16, d16, d28 // t16a 2029 vqsub.s16 d19, d30, d23 // t20a 2030 vqadd.s16 d30, d30, d23 // t23a 2031 vqsub.s16 d28, d17, d22 // t21 2032 vqadd.s16 d17, d17, d22 // t22 2033 vqadd.s16 d23, d26, d29 // t24a 2034 vqsub.s16 d26, d26, d29 // t27a 2035 vqadd.s16 d22, d20, d18 // t25 2036 vqsub.s16 d20, d20, d18 // t26 2037 vqsub.s16 d29, d31, d25 // t28a 2038 vqadd.s16 d31, d31, d25 // t31a 2039 2040 vmull_vmlsl q2, d2, d3, d0[2], d0[3] // -> t18a 2041 vmull_vmlal q3, d2, d3, d0[3], d0[2] // -> t29a 2042 vmull_vmlsl q4, d29, d24, d0[2], d0[3] // -> t19 2043 vqrshrn.s32 d18, q2, #12 // t18a 2044 vqrshrn.s32 d25, q3, #12 // t29a 2045 vmull_vmlal q1, d29, d24, d0[3], d0[2] // -> t28 2046 vmull_vmlal q2, d26, d19, d0[3], d0[2] // -> t20 2047 vqrshrn.s32 d29, q4, #12 // t19 2048 vqrshrn.s32 d24, q1, #12 // t28 2049 vneg.s32 q2, q2 // -> t20 2050 vmull_vmlsl q3, d26, d19, d0[2], d0[3] // -> t27 2051 vmull_vmlal q4, d20, d28, d0[3], d0[2] // -> t21a 2052 vqrshrn.s32 d26, q2, #12 // t20 2053 vqrshrn.s32 d19, q3, #12 // t27 2054 vneg.s32 q4, q4 // -> t21a 2055 vmull_vmlsl q1, d20, d28, d0[2], d0[3] // -> t26a 2056 vqrshrn.s32 d20, q4, #12 // t21a 2057 vqrshrn.s32 d28, q1, #12 // t26a 2058 2059 vqsub.s16 d2, d16, d30 // t23 2060 vqadd.s16 d16, d16, d30 // t16 = out16 2061 vqsub.s16 d3, d31, d23 // t24 2062 vqadd.s16 d31, d31, d23 // t31 = out31 2063 vqsub.s16 d23, d21, d17 // t22a 2064 vqadd.s16 d17, d21, d17 // t17a = out17 2065 vqadd.s16 d30, d27, d22 // t30a = out30 2066 vqsub.s16 d21, d27, d22 // t25a 2067 vqsub.s16 d27, d18, d20 // t21 2068 vqadd.s16 d18, d18, d20 // t18 = out18 2069 vqadd.s16 d4, d29, d26 // t19a = out19 2070 vqsub.s16 d26, d29, d26 // t20a 2071 vqadd.s16 d29, d25, d28 // t29 = out29 2072 vqsub.s16 d25, d25, d28 // t26 2073 vqadd.s16 d28, d24, d19 // t28a = out28 2074 vqsub.s16 d24, d24, d19 // t27a 2075 vmov d19, d4 // out19 2076 2077 vmull_vmlsl q2, d24, d26, d0[0], d0[0] // -> t20 2078 vmull_vmlal q3, d24, d26, d0[0], d0[0] // -> t27 2079 vqrshrn.s32 d20, q2, #12 // t20 2080 vqrshrn.s32 d22, q3, #12 // t27 2081 2082 vmull_vmlal q2, d25, d27, d0[0], d0[0] // -> t26a 2083 vmull_vmlsl q3, d25, d27, d0[0], d0[0] // -> t21a 2084 vmov d27, d22 // t27 2085 vqrshrn.s32 d26, q2, #12 // t26a 2086 2087 vmull_vmlsl q12, d21, d23, d0[0], d0[0] // -> t22 2088 vmull_vmlal q2, d21, d23, d0[0], d0[0] // -> t25 2089 vqrshrn.s32 d21, q3, #12 // t21a 2090 vqrshrn.s32 d22, q12, #12 // t22 2091 vqrshrn.s32 d25, q2, #12 // t25 2092 2093 vmull_vmlsl q2, d3, d2, d0[0], d0[0] // -> t23a 2094 vmull_vmlal q3, d3, d2, d0[0], d0[0] // -> t24a 2095 vqrshrn.s32 d23, q2, #12 // t23a 2096 vqrshrn.s32 d24, q3, #12 // t24a 2097 2098 bx lr 2099endfunc 2100 2101.macro def_horz_32 scale=0, shift=2, suffix 2102function inv_txfm_horz\suffix\()_dct_32x4_neon 2103 push {lr} 2104 vmov.i16 d7, #0 2105 lsl r8, r8, #1 2106.if \scale 2107 movw r12, #2896*8 2108 vdup.16 d0, r12 2109.endif 2110 2111.irp i, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 2112 vld1.16 {\i}, [r7, :64] 2113 vst1.16 {d7}, [r7, :64], r8 2114.endr 2115 sub r7, r7, r8, lsl #4 2116 add r7, r7, r8, lsr #1 2117.if \scale 2118 scale_input d0[0], q8, q9, q10, q11, q12, q13, q14, q15 2119.endif 2120 bl inv_dct_4h_x16_neon 2121 transpose_4x4h q8, q9, d16, d17, d18, d19 2122 transpose_4x4h q10, q11, d20, d21, d22, d23 2123 transpose_4x4h q12, q13, d24, d25, d26, d27 2124 transpose_4x4h q14, q15, d28, d29, d30, d31 2125 2126.macro store1 r0, r1, r2, r3 2127 vst1.16 {\r0}, [r6, :64]! 2128 vst1.16 {\r1}, [r6, :64]! 2129 vst1.16 {\r2}, [r6, :64]! 2130 vst1.16 {\r3}, [r6, :64]! 2131 add r6, r6, #32 2132.endm 2133 store1 d16, d20, d24, d28 2134 store1 d17, d21, d25, d29 2135 store1 d18, d22, d26, d30 2136 store1 d19, d23, d27, d31 2137.purgem store1 2138 sub r6, r6, #64*4 2139 2140 vmov.i16 d7, #0 2141.irp i, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 2142 vld1.16 {\i}, [r7, :64] 2143 vst1.16 {d7}, [r7, :64], r8 2144.endr 2145.if \scale 2146 // This relies on the fact that the idct also leaves the right coeff in d0[1] 2147 scale_input d0[1], q8, q9, q10, q11, q12, q13, q14, q15 2148.endif 2149 bl inv_dct32_odd_4h_x16_neon 2150 transpose_4x4h q15, q14, d31, d30, d29, d28 2151 transpose_4x4h q13, q12, d27, d26, d25, d24 2152 transpose_4x4h q11, q10, d23, d22, d21, d20 2153 transpose_4x4h q9, q8, d19, d18, d17, d16 2154.macro store2 r0, r1, r2, r3, shift 2155 vld1.16 {q0, q1}, [r6, :128] 2156 vqsub.s16 d7, d0, \r0 2157 vqadd.s16 d0, d0, \r0 2158 vqsub.s16 d6, d1, \r1 2159 vqadd.s16 d1, d1, \r1 2160 vqsub.s16 d5, d2, \r2 2161 vqadd.s16 d2, d2, \r2 2162 vqsub.s16 d4, d3, \r3 2163 vqadd.s16 d3, d3, \r3 2164 vrev64.16 q2, q2 2165 vrev64.16 q3, q3 2166 vrshr.s16 q0, q0, #\shift 2167 vrshr.s16 q1, q1, #\shift 2168 vrshr.s16 q2, q2, #\shift 2169 vrshr.s16 q3, q3, #\shift 2170 vst1.16 {q0, q1}, [r6, :128]! 2171 vst1.16 {q2, q3}, [r6, :128]! 2172.endm 2173 2174 store2 d31, d27, d23, d19, \shift 2175 store2 d30, d26, d22, d18, \shift 2176 store2 d29, d25, d21, d17, \shift 2177 store2 d28, d24, d20, d16, \shift 2178.purgem store2 2179 pop {pc} 2180endfunc 2181.endm 2182 2183def_horz_32 scale=0, shift=2 2184def_horz_32 scale=1, shift=1, suffix=_scale 2185 2186function inv_txfm_add_vert_dct_4x32_neon 2187 push {r10-r11,lr} 2188 lsl r8, r8, #1 2189 2190.irp i, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 2191 vld1.16 {\i}, [r7, :64], r8 2192.endr 2193 sub r7, r7, r8, lsl #4 2194 2195 bl inv_dct_4h_x16_neon 2196 2197.irp i, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 2198 vst1.16 {\i}, [r7, :64], r8 2199.endr 2200 sub r7, r7, r8, lsl #4 2201 add r7, r7, r8, lsr #1 2202 2203.irp i, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31 2204 vld1.16 {\i}, [r7, :64], r8 2205.endr 2206 sub r7, r7, r8, lsl #4 2207 sub r7, r7, r8, lsr #1 2208 bl inv_dct32_odd_4h_x16_neon 2209 2210 neg r9, r8 2211 mov r10, r6 2212.macro combine r0, r1, r2, r3, op, stride 2213 vld1.16 {d4}, [r7, :64], \stride 2214 vld1.32 {d2[0]}, [r10, :32], r1 2215 vld1.16 {d5}, [r7, :64], \stride 2216 vld1.32 {d2[1]}, [r10, :32], r1 2217 \op\().s16 d4, d4, \r0 2218 vld1.16 {d6}, [r7, :64], \stride 2219 vld1.32 {d3[0]}, [r10, :32], r1 2220 \op\().s16 d5, d5, \r1 2221 vld1.32 {d3[1]}, [r10, :32], r1 2222 vrshr.s16 q2, q2, #4 2223 \op\().s16 d6, d6, \r2 2224 vld1.16 {d7}, [r7, :64], \stride 2225 vaddw.u8 q2, q2, d2 2226 \op\().s16 d7, d7, \r3 2227 vqmovun.s16 d2, q2 2228 vrshr.s16 q3, q3, #4 2229 vst1.32 {d2[0]}, [r6, :32], r1 2230 vaddw.u8 q3, q3, d3 2231 vst1.32 {d2[1]}, [r6, :32], r1 2232 vqmovun.s16 d3, q3 2233 vst1.32 {d3[0]}, [r6, :32], r1 2234 vst1.32 {d3[1]}, [r6, :32], r1 2235.endm 2236 combine d31, d30, d29, d28, vqadd, r8 2237 combine d27, d26, d25, d24, vqadd, r8 2238 combine d23, d22, d21, d20, vqadd, r8 2239 combine d19, d18, d17, d16, vqadd, r8 2240 sub r7, r7, r8 2241 combine d16, d17, d18, d19, vqsub, r9 2242 combine d20, d21, d22, d23, vqsub, r9 2243 combine d24, d25, d26, d27, vqsub, r9 2244 combine d28, d29, d30, d31, vqsub, r9 2245.purgem combine 2246 2247 pop {r10-r11,pc} 2248endfunc 2249 2250const eob_32x32 2251 .short 10, 36, 78, 136, 210, 300, 406, 1024 2252endconst 2253 2254const eob_16x32 2255 .short 10, 36, 78, 151, 215, 279, 343, 512 2256endconst 2257 2258const eob_16x32_shortside 2259 .short 10, 36, 78, 512 2260endconst 2261 2262const eob_8x32 2263 // Contrary to the others, this one is only ever used in increments of 8x8 2264 .short 43, 107, 171, 256 2265endconst 2266 2267function inv_txfm_add_identity_identity_32x32_8bpc_neon, export=1 2268 push {r4-r7,lr} 2269 vmov.i16 q0, #0 2270 movrel_local r5, eob_32x32, 2 2271 2272 mov r6, #2*32 22731: 2274 mov r12, #0 2275 movrel_local r4, eob_32x32, 2 22762: 2277 add r12, r12, #8 2278.irp i, q8, q9, q10, q11, q12, q13, q14, q15 2279 vld1.16 {\i}, [r2, :128] 2280 vst1.16 {q0}, [r2, :128], r6 2281.endr 2282 transpose_8x8h q8, q9, q10, q11, q12, q13, q14, q15, d17, d19, d21, d23, d24, d26, d28, d30 2283 2284 load_add_store_8x8 r0, r7, shiftbits=2 2285 ldrh lr, [r4], #4 2286 sub r0, r0, r1, lsl #3 2287 cmp r3, lr 2288 add r0, r0, #8 2289 bge 2b 2290 2291 ldrh lr, [r5], #4 2292 cmp r3, lr 2293 blt 9f 2294 2295 sub r0, r0, r12 2296 add r0, r0, r1, lsl #3 2297 mls r2, r6, r12, r2 2298 add r2, r2, #2*8 2299 b 1b 23009: 2301 pop {r4-r7,pc} 2302endfunc 2303 2304.macro shift_8_regs op, shift 2305.irp i, q8, q9, q10, q11, q12, q13, q14, q15 2306 \op \i, \i, #\shift 2307.endr 2308.endm 2309 2310.macro def_identity_1632 w, h, wshort, hshort 2311function inv_txfm_add_identity_identity_\w\()x\h\()_8bpc_neon, export=1 2312 push {r4-r7,lr} 2313 movw r6, #2896*8 2314 movw r7, #2*(5793-4096)*8 2315 vdup.i16 d0, r6 2316 movrel_local r5, eob_16x32\hshort, 2 2317 vmov.16 d0[1], r7 2318 2319 mov r6, #2*\h 23201: 2321 mov r12, #0 2322 movrel_local r4, eob_16x32\wshort, 2 23232: 2324 vmov.i16 q1, #0 2325 add r12, r12, #8 2326.irp i, q8, q9, q10, q11, q12, q13, q14, q15 2327 vld1.16 {\i}, [r2, :128] 2328 vst1.16 {q1}, [r2, :128], r6 2329.endr 2330 scale_input d0[0], q8, q9, q10, q11, q12, q13, q14, q15 2331 2332.if \w == 16 2333 // 16x32 2334 identity_8x8_shift1 d0[1] 2335.else 2336 // 32x16 2337 shift_8_regs vqshl.s16, 1 2338 identity_8x8 d0[1] 2339.endif 2340 2341 transpose_8x8h q8, q9, q10, q11, q12, q13, q14, q15, d17, d19, d21, d23, d24, d26, d28, d30 2342 2343.if \w == 16 2344 load_add_store_8x8 r0, r7, shiftbits=2 2345.else 2346 load_add_store_8x8 r0, r7, shiftbits=4 2347.endif 2348 ldrh lr, [r4], #4 2349 sub r0, r0, r1, lsl #3 2350 cmp r3, lr 2351 add r0, r0, #8 2352 bge 2b 2353 2354 ldrh lr, [r5], #4 2355 cmp r3, lr 2356 blt 9f 2357 2358 sub r0, r0, r12 2359 add r0, r0, r1, lsl #3 2360 mls r2, r6, r12, r2 2361 add r2, r2, #2*8 2362 b 1b 23639: 2364 pop {r4-r7,pc} 2365endfunc 2366.endm 2367 2368def_identity_1632 16, 32, _shortside, 2369def_identity_1632 32, 16, , _shortside 2370 2371.macro def_identity_832 w, h 2372function inv_txfm_add_identity_identity_\w\()x\h\()_8bpc_neon, export=1 2373 push {r4-r5,lr} 2374 vmov.i16 q0, #0 2375 movrel_local r4, eob_8x32 2376 2377 mov r12, #2*\h 23781: 2379 ldrh lr, [r4], #2 2380.irp i, q8, q9, q10, q11, q12, q13, q14, q15 2381 vld1.16 {\i}, [r2, :128] 2382 vst1.16 {q0}, [r2, :128], r12 2383.endr 2384 2385.if \w == 8 2386 // 8x32 2387 shift_8_regs vrshr.s16, 1 2388.endif 2389 2390 transpose_8x8h q8, q9, q10, q11, q12, q13, q14, q15, d17, d19, d21, d23, d24, d26, d28, d30 2391 2392 cmp r3, lr 2393.if \w == 8 2394 load_add_store_8x8 r0, r5, shiftbits=2 2395.else 2396 load_add_store_8x8 r0, r5, shiftbits=3 2397.endif 2398 2399 blt 9f 2400.if \w == 8 2401 sub r2, r2, r12, lsl #3 2402 add r2, r2, #2*8 2403.else 2404 sub r0, r0, r1, lsl #3 2405 add r0, r0, #8 2406.endif 2407 b 1b 2408 24099: 2410 pop {r4-r5,pc} 2411endfunc 2412.endm 2413 2414def_identity_832 8, 32 2415def_identity_832 32, 8 2416 2417function inv_txfm_add_dct_dct_32x32_8bpc_neon, export=1 2418 idct_dc 32, 32, 2 2419 2420 push {r4-r11,lr} 2421 vpush {q4} 2422 sub_sp_align 2048 2423 movrel_local r10, eob_32x32 2424 ldrh r11, [r10], #2 2425 2426.irp i, 0, 4, 8, 12, 16, 20, 24, 28 2427 add r6, sp, #(\i*32*2) 2428.if \i > 0 2429 mov r8, #(32 - \i) 2430 cmp r3, r11 2431 blt 1f 2432.if \i < 28 2433 ldrh r11, [r10], #2 2434.endif 2435.endif 2436 add r7, r2, #(\i*2) 2437 mov r8, #32*2 2438 bl inv_txfm_horz_dct_32x4_neon 2439.endr 2440 b 3f 2441 24421: 2443 vmov.i16 q2, #0 2444 vmov.i16 q3, #0 24452: 2446 subs r8, r8, #2 2447.rept 4 2448 vst1.16 {q2, q3}, [r6, :128]! 2449.endr 2450 bgt 2b 2451 24523: 2453.irp i, 0, 4, 8, 12, 16, 20, 24, 28 2454 add r6, r0, #(\i) 2455 add r7, sp, #(\i*2) 2456 mov r8, #32*2 2457 bl inv_txfm_add_vert_dct_4x32_neon 2458.endr 2459 2460 add_sp_align 2048 2461 vpop {q4} 2462 pop {r4-r11,pc} 2463endfunc 2464 2465function inv_txfm_add_dct_dct_16x32_8bpc_neon, export=1 2466 idct_dc 16, 32, 1 2467 2468 push {r4-r11,lr} 2469 vpush {q4} 2470 sub_sp_align 1024 2471 movrel_local r10, eob_16x32 2472 ldrh r11, [r10], #2 2473 movrel_local r4, inv_dct_4h_x16_neon 2474 2475.irp i, 0, 4, 8, 12, 16, 20, 24, 28 2476 add r6, sp, #(\i*16*2) 2477 add r7, r2, #(\i*2) 2478.if \i > 0 2479 mov r8, #(32 - \i) 2480 cmp r3, r11 2481 blt 1f 2482.if \i < 28 2483 ldrh r11, [r10], #2 2484.endif 2485.endif 2486 mov r8, #2*32 2487 bl inv_txfm_horz_scale_16x4_neon 2488.endr 2489 b 3f 2490 24911: 2492 vmov.i16 q2, #0 2493 vmov.i16 q3, #0 24942: 2495 subs r8, r8, #4 2496.rept 4 2497 vst1.16 {q2, q3}, [r6, :128]! 2498.endr 2499 bgt 2b 2500 25013: 2502.irp i, 0, 4, 8, 12 2503 add r6, r0, #(\i) 2504 add r7, sp, #(\i*2) 2505 mov r8, #16*2 2506 bl inv_txfm_add_vert_dct_4x32_neon 2507.endr 2508 2509 add_sp_align 1024 2510 vpop {q4} 2511 pop {r4-r11,pc} 2512endfunc 2513 2514function inv_txfm_add_dct_dct_32x16_8bpc_neon, export=1 2515 idct_dc 32, 16, 1 2516 2517 push {r4-r11,lr} 2518 vpush {q4} 2519 sub_sp_align 1024 2520 movrel_local r10, eob_16x32 2521 ldrh r11, [r10], #2 2522 movrel_local r5, inv_dct_4h_x16_neon 2523 2524.irp i, 0, 4, 8, 12 2525 add r6, sp, #(\i*32*2) 2526 add r7, r2, #(\i*2) 2527.if \i > 0 2528 mov r8, #(16 - \i) 2529 cmp r3, r11 2530 blt 1f 2531.if \i < 12 2532 ldrh r11, [r10], #2 2533.endif 2534.endif 2535 mov r8, #2*16 2536 bl inv_txfm_horz_scale_dct_32x4_neon 2537.endr 2538 b 3f 2539 25401: 2541 vmov.i16 q2, #0 2542 vmov.i16 q3, #0 25432: 2544 subs r8, r8, #2 2545.rept 4 2546 vst1.16 {q2, q3}, [r6, :128]! 2547.endr 2548 bgt 2b 2549 25503: 2551.irp i, 0, 4, 8, 12, 16, 20, 24, 28 2552 add r6, r0, #(\i) 2553 add r7, sp, #(\i*2) 2554 mov r8, #32*2 2555 bl inv_txfm_add_vert_4x16_neon 2556.endr 2557 2558 add_sp_align 1024 2559 vpop {q4} 2560 pop {r4-r11,pc} 2561endfunc 2562 2563function inv_txfm_add_dct_dct_8x32_8bpc_neon, export=1 2564 idct_dc 8, 32, 2 2565 2566 push {r4-r11,lr} 2567 vpush {q4-q7} 2568 sub_sp_align 512 2569 2570 movrel_local r10, eob_8x32 2571 2572 mov r8, #2*32 2573 mov r9, #32 2574 mov r6, sp 25751: 2576 vmov.i16 q0, #0 2577.irp i, q8, q9, q10, q11, q12, q13, q14, q15 2578 vld1.16 {\i}, [r2, :128] 2579 vst1.16 {q0}, [r2, :128], r8 2580.endr 2581 ldrh r11, [r10], #2 2582 sub r2, r2, r8, lsl #3 2583 sub r9, r9, #8 2584 add r2, r2, #2*8 2585 2586 bl inv_dct_8h_x8_neon 2587 2588.irp i, q8, q9, q10, q11, q12, q13, q14, q15 2589 vrshr.s16 \i, \i, #2 2590.endr 2591 2592 transpose_8x8h q8, q9, q10, q11, q12, q13, q14, q15, d17, d19, d21, d23, d24, d26, d28, d30 2593 2594 vst1.16 {q8, q9}, [r6, :128]! 2595 cmp r3, r11 2596 vst1.16 {q10, q11}, [r6, :128]! 2597 vst1.16 {q12, q13}, [r6, :128]! 2598 vst1.16 {q14, q15}, [r6, :128]! 2599 2600 bge 1b 2601 cmp r9, #0 2602 beq 3f 2603 2604 vmov.i16 q2, #0 2605 vmov.i16 q3, #0 26062: 2607 subs r9, r9, #8 2608.rept 4 2609 vst1.16 {q2, q3}, [r6, :128]! 2610.endr 2611 bgt 2b 2612 26133: 2614.irp i, 0, 4 2615 add r6, r0, #(\i) 2616 add r7, sp, #(\i*2) 2617 mov r8, #8*2 2618 bl inv_txfm_add_vert_dct_4x32_neon 2619.endr 2620 2621 add_sp_align 512 2622 vpop {q4-q7} 2623 pop {r4-r11,pc} 2624endfunc 2625 2626function inv_txfm_add_dct_dct_32x8_8bpc_neon, export=1 2627 idct_dc 32, 8, 2 2628 2629 push {r4-r11,lr} 2630 vpush {q4-q7} 2631 sub_sp_align 512 2632 2633.irp i, 0, 4 2634 add r6, sp, #(\i*32*2) 2635 add r7, r2, #(\i*2) 2636.if \i > 0 2637 cmp r3, #10 2638 blt 1f 2639.endif 2640 mov r8, #8*2 2641 bl inv_txfm_horz_dct_32x4_neon 2642.endr 2643 b 2f 2644 26451: 2646 vmov.i16 q2, #0 2647 vmov.i16 q3, #0 2648.rept 8 2649 vst1.16 {q2, q3}, [r6, :128]! 2650.endr 2651 26522: 2653 mov r8, #2*32 2654 mov r9, #0 26551: 2656 add r6, r0, r9 2657 add r7, sp, r9, lsl #1 // #(\i*2) 2658 2659.irp i, q8, q9, q10, q11, q12, q13, q14, q15 2660 vld1.16 {\i}, [r7, :128], r8 2661.endr 2662 add r9, r9, #8 2663 2664 bl inv_dct_8h_x8_neon 2665 2666 cmp r9, #32 2667 2668 load_add_store_8x8 r6, r7 2669 2670 blt 1b 2671 2672 add_sp_align 512 2673 vpop {q4-q7} 2674 pop {r4-r11,pc} 2675endfunc 2676 2677function inv_dct64_step1_neon 2678 // in1/31/17/15 -> t32a/33/34a/35/60/61a/62/63a 2679 // in7/25/23/ 9 -> t56a/57/58a/59/36/37a/38/39a 2680 // in5/27/21/11 -> t40a/41/42a/43/52/53a/54/55a 2681 // in3/29/19/13 -> t48a/49/50a/51/44/45a/46/47a 2682 2683 vld1.16 {d0, d1, d2}, [r12, :64]! 2684 2685 vqrdmulh.s16 d23, d16, d0[1] // t63a 2686 vqrdmulh.s16 d16, d16, d0[0] // t32a 2687 vqrdmulh.s16 d22, d17, d0[2] // t62a 2688 vqrdmulh.s16 d17, d17, d0[3] // t33a 2689 vqrdmulh.s16 d21, d18, d1[1] // t61a 2690 vqrdmulh.s16 d18, d18, d1[0] // t34a 2691 vqrdmulh.s16 d20, d19, d1[2] // t60a 2692 vqrdmulh.s16 d19, d19, d1[3] // t35a 2693 2694 vqadd.s16 d24, d16, d17 // t32 2695 vqsub.s16 d25, d16, d17 // t33 2696 vqsub.s16 d26, d19, d18 // t34 2697 vqadd.s16 d27, d19, d18 // t35 2698 vqadd.s16 d28, d20, d21 // t60 2699 vqsub.s16 d29, d20, d21 // t61 2700 vqsub.s16 d30, d23, d22 // t62 2701 vqadd.s16 d31, d23, d22 // t63 2702 2703 vmull_vmlal q2, d29, d26, d2[0], d2[1] // -> t34a 2704 vmull_vmlsl q3, d29, d26, d2[1], d2[0] // -> t61a 2705 vneg.s32 q2, q2 // t34a 2706 vmull_vmlsl q4, d30, d25, d2[1], d2[0] // -> t33a 2707 vqrshrn.s32 d26, q2, #12 // t34a 2708 vmull_vmlal q2, d30, d25, d2[0], d2[1] // -> t62a 2709 vqrshrn.s32 d29, q3, #12 // t61a 2710 vqrshrn.s32 d25, q4, #12 // t33a 2711 vqrshrn.s32 d30, q2, #12 // t62a 2712 2713 vqadd.s16 d16, d24, d27 // t32a 2714 vqsub.s16 d19, d24, d27 // t35a 2715 vqadd.s16 d17, d25, d26 // t33 2716 vqsub.s16 d18, d25, d26 // t34 2717 vqsub.s16 d20, d31, d28 // t60a 2718 vqadd.s16 d23, d31, d28 // t63a 2719 vqsub.s16 d21, d30, d29 // t61 2720 vqadd.s16 d22, d30, d29 // t62 2721 2722 vmull_vmlal q2, d21, d18, d2[2], d2[3] // -> t61a 2723 vmull_vmlsl q3, d21, d18, d2[3], d2[2] // -> t34a 2724 vmull_vmlal q4, d20, d19, d2[2], d2[3] // -> t60 2725 vqrshrn.s32 d21, q2, #12 // t61a 2726 vqrshrn.s32 d18, q3, #12 // t34a 2727 vmull_vmlsl q2, d20, d19, d2[3], d2[2] // -> t35 2728 vqrshrn.s32 d20, q4, #12 // t60 2729 vqrshrn.s32 d19, q2, #12 // t35 2730 2731 vst1.16 {d16, d17, d18, d19}, [r6, :128]! 2732 vst1.16 {d20, d21, d22, d23}, [r6, :128]! 2733 2734 bx lr 2735endfunc 2736 2737function inv_dct64_step2_neon 2738 movrel_local r12, idct_coeffs 2739 vld1.16 {d0}, [r12, :64] 27401: 2741 // t32a/33/34a/35/60/61a/62/63a 2742 // t56a/57/58a/59/36/37a/38/39a 2743 // t40a/41/42a/43/52/53a/54/55a 2744 // t48a/49/50a/51/44/45a/46/47a 2745 vldr d16, [r6, #2*4*0] // t32a 2746 vldr d17, [r9, #2*4*8] // t39a 2747 vldr d18, [r9, #2*4*0] // t63a 2748 vldr d19, [r6, #2*4*8] // t56a 2749 vldr d20, [r6, #2*4*16] // t40a 2750 vldr d21, [r9, #2*4*24] // t47a 2751 vldr d22, [r9, #2*4*16] // t55a 2752 vldr d23, [r6, #2*4*24] // t48a 2753 2754 vqadd.s16 d24, d16, d17 // t32 2755 vqsub.s16 d25, d16, d17 // t39 2756 vqadd.s16 d26, d18, d19 // t63 2757 vqsub.s16 d27, d18, d19 // t56 2758 vqsub.s16 d28, d21, d20 // t40 2759 vqadd.s16 d29, d21, d20 // t47 2760 vqadd.s16 d30, d23, d22 // t48 2761 vqsub.s16 d31, d23, d22 // t55 2762 2763 vmull_vmlal q2, d27, d25, d0[3], d0[2] // -> t56a 2764 vmull_vmlsl q3, d27, d25, d0[2], d0[3] // -> t39a 2765 vmull_vmlal q4, d31, d28, d0[3], d0[2] // -> t40a 2766 vqrshrn.s32 d25, q2, #12 // t56a 2767 vqrshrn.s32 d27, q3, #12 // t39a 2768 vneg.s32 q4, q4 // t40a 2769 vmull_vmlsl q2, d31, d28, d0[2], d0[3] // -> t55a 2770 vqrshrn.s32 d31, q4, #12 // t40a 2771 vqrshrn.s32 d28, q2, #12 // t55a 2772 2773 vqadd.s16 d16, d24, d29 // t32a 2774 vqsub.s16 d19, d24, d29 // t47a 2775 vqadd.s16 d17, d27, d31 // t39 2776 vqsub.s16 d18, d27, d31 // t40 2777 vqsub.s16 d20, d26, d30 // t48a 2778 vqadd.s16 d23, d26, d30 // t63a 2779 vqsub.s16 d21, d25, d28 // t55 2780 vqadd.s16 d22, d25, d28 // t56 2781 2782 vmull_vmlsl q2, d21, d18, d0[0], d0[0] // -> t40a 2783 vmull_vmlal q3, d21, d18, d0[0], d0[0] // -> t55a 2784 vmull_vmlsl q4, d20, d19, d0[0], d0[0] // -> t47 2785 vqrshrn.s32 d18, q2, #12 // t40a 2786 vqrshrn.s32 d21, q3, #12 // t55a 2787 vmull_vmlal q2, d20, d19, d0[0], d0[0] // -> t48 2788 vqrshrn.s32 d19, q4, #12 // t47 2789 vqrshrn.s32 d20, q2, #12 // t48 2790 2791 vstr d16, [r6, #2*4*0] // t32a 2792 vstr d17, [r9, #2*4*0] // t39 2793 vstr d18, [r6, #2*4*8] // t40a 2794 vstr d19, [r9, #2*4*8] // t47 2795 vstr d20, [r6, #2*4*16] // t48 2796 vstr d21, [r9, #2*4*16] // t55a 2797 vstr d22, [r6, #2*4*24] // t56 2798 vstr d23, [r9, #2*4*24] // t63a 2799 2800 add r6, r6, #2*4 2801 sub r9, r9, #2*4 2802 cmp r6, r9 2803 blt 1b 2804 bx lr 2805endfunc 2806 2807.macro load8 src, strd, zero, clear 2808.irp i, d16, d17, d18, d19, d20, d21, d22, d23 2809.if \clear 2810 vld1.16 {\i}, [\src, :64] 2811 vst1.16 {\zero}, [\src, :64], \strd 2812.else 2813 vld1.16 {\i}, [\src, :64], \strd 2814.endif 2815.endr 2816.endm 2817 2818.macro store16 dst 2819 vst1.16 {q8, q9}, [\dst, :128]! 2820 vst1.16 {q10, q11}, [\dst, :128]! 2821 vst1.16 {q12, q13}, [\dst, :128]! 2822 vst1.16 {q14, q15}, [\dst, :128]! 2823.endm 2824 2825.macro clear_upper8 2826.irp i, q12, q13, q14, q15 2827 vmov.i16 \i, #0 2828.endr 2829.endm 2830 2831.macro vmov_if reg, val, cond 2832.if \cond 2833 vmov.i16 \reg, \val 2834.endif 2835.endm 2836 2837.macro movdup_if reg, gpr, val, cond 2838.if \cond 2839 movw \gpr, \val 2840 vdup.16 \reg, \gpr 2841.endif 2842.endm 2843 2844.macro vst1_if regs, dst, dstalign, cond 2845.if \cond 2846 vst1.16 \regs, \dst, \dstalign 2847.endif 2848.endm 2849 2850.macro scale_if cond, c, r0, r1, r2, r3, r4, r5, r6, r7 2851.if \cond 2852 scale_input \c, \r0, \r1, \r2, \r3, \r4, \r5, \r6, \r7 2853.endif 2854.endm 2855 2856.macro def_dct64_func suffix, clear=0, scale=0 2857function inv_txfm_dct\suffix\()_4h_x64_neon, export=1 2858 mov r6, sp 2859 2860 push {r10-r11,lr} 2861 2862 lsl r8, r8, #2 2863 2864 movdup_if d0, r12, #2896*8, \scale 2865 vmov_if d7, #0, \clear 2866 load8 r7, r8, d7, \clear 2867 clear_upper8 2868 sub r7, r7, r8, lsl #3 2869 add r7, r7, r8, lsr #1 2870 scale_if \scale, d0[0], q8, q9, q10, q11 2871 2872 bl inv_dct_4h_x16_neon 2873 2874 store16 r6 2875 2876 movdup_if d0, r12, #2896*8, \scale 2877 vmov_if d7, #0, \clear 2878 load8 r7, r8, d7, \clear 2879 clear_upper8 2880 sub r7, r7, r8, lsl #3 2881 lsr r8, r8, #1 2882 sub r7, r7, r8, lsr #1 2883 scale_if \scale, d0[0], q8, q9, q10, q11 2884 2885 bl inv_dct32_odd_4h_x16_neon 2886 2887 add r10, r6, #8*15 2888 sub r6, r6, #8*16 2889 2890 mov r9, #-8 2891 2892.macro store_addsub r0, r1, r2, r3 2893 vld1.16 {d2}, [r6, :64]! 2894 vld1.16 {d3}, [r6, :64]! 2895 vqadd.s16 d6, d2, \r0 2896 vqsub.s16 \r0, d2, \r0 2897 vld1.16 {d4}, [r6, :64]! 2898 vqadd.s16 d7, d3, \r1 2899 vqsub.s16 \r1, d3, \r1 2900 vld1.16 {d5}, [r6, :64]! 2901 vqadd.s16 d2, d4, \r2 2902 sub r6, r6, #8*4 2903 vqsub.s16 \r2, d4, \r2 2904 vst1.16 {d6}, [r6, :64]! 2905 vst1.16 {\r0}, [r10, :64], r9 2906 vqadd.s16 d3, d5, \r3 2907 vqsub.s16 \r3, d5, \r3 2908 vst1.16 {d7}, [r6, :64]! 2909 vst1.16 {\r1}, [r10, :64], r9 2910 vst1.16 {d2}, [r6, :64]! 2911 vst1.16 {\r2}, [r10, :64], r9 2912 vst1.16 {d3}, [r6, :64]! 2913 vst1.16 {\r3}, [r10, :64], r9 2914.endm 2915 store_addsub d31, d30, d29, d28 2916 store_addsub d27, d26, d25, d24 2917 store_addsub d23, d22, d21, d20 2918 store_addsub d19, d18, d17, d16 2919.purgem store_addsub 2920 2921 add r6, r6, #2*4*16 2922 2923 movrel_local r12, idct64_coeffs 2924 movdup_if d0, lr, #2896*8, \scale 2925 vmov_if d7, #0, \clear 2926 add r9, r7, r8, lsl #4 // offset 16 2927 add r10, r7, r8, lsl #3 // offset 8 2928 sub r9, r9, r8 // offset 15 2929 sub r11, r10, r8 // offset 7 2930 vld1.16 {d16}, [r7, :64] // in1 (offset 0) 2931 vld1.16 {d17}, [r9, :64] // in31 (offset 15) 2932 vld1.16 {d18}, [r10, :64] // in17 (offset 8) 2933 vld1.16 {d19}, [r11, :64] // in15 (offset 7) 2934 vst1_if {d7}, [r7, :64], \clear 2935 vst1_if {d7}, [r9, :64], \clear 2936 vst1_if {d7}, [r10, :64], \clear 2937 vst1_if {d7}, [r11, :64], \clear 2938 scale_if \scale, d0[0], q8, q9 2939 bl inv_dct64_step1_neon 2940 movdup_if d0, lr, #2896*8, \scale 2941 vmov_if d7, #0, \clear 2942 add r7, r7, r8, lsl #2 // offset 4 2943 sub r9, r9, r8, lsl #2 // offset 11 2944 sub r10, r7, r8 // offset 3 2945 add r11, r9, r8 // offset 12 2946 vld1.16 {d16}, [r10, :64] // in7 (offset 3) 2947 vld1.16 {d17}, [r11, :64] // in25 (offset 12) 2948 vld1.16 {d18}, [r9, :64] // in23 (offset 11) 2949 vld1.16 {d19}, [r7, :64] // in9 (offset 4) 2950 vst1_if {d7}, [r7, :64], \clear 2951 vst1_if {d7}, [r9, :64], \clear 2952 vst1_if {d7}, [r10, :64], \clear 2953 vst1_if {d7}, [r11, :64], \clear 2954 scale_if \scale, d0[0], q8, q9 2955 bl inv_dct64_step1_neon 2956 movdup_if d0, lr, #2896*8, \scale 2957 vmov_if d7, #0, \clear 2958 sub r10, r10, r8, lsl #1 // offset 1 2959 sub r9, r9, r8, lsl #1 // offset 9 2960 add r10, r10, r8 // offset 2 2961 add r9, r9, r8 // offset 10 2962 add r7, r7, r8 // offset 5 2963 add r11, r11, r8 // offset 13 2964 vld1.16 d16, [r10, :64] // in5 (offset 2) 2965 vld1.16 d17, [r11, :64] // in27 (offset 13) 2966 vld1.16 d18, [r9, :64] // in21 (offset 10) 2967 vld1.16 d19, [r7, :64] // in11 (offset 5) 2968 vst1_if d7, [r10, :64], \clear 2969 vst1_if d7, [r11, :64], \clear 2970 vst1_if d7, [r9, :64], \clear 2971 vst1_if d7, [r7, :64], \clear 2972 scale_if \scale, d0[0], q8, q9 2973 bl inv_dct64_step1_neon 2974 movdup_if d0, lr, #2896*8, \scale 2975 vmov_if d7, #0, \clear 2976 sub r10, r10, r8 // offset 1 2977 sub r9, r9, r8 // offset 9 2978 add r11, r11, r8 // offset 14 2979 add r7, r7, r8 // offset 6 2980 vld1.16 d16, [r10, :64] // in3 (offset 1) 2981 vld1.16 d17, [r11, :64] // in29 (offset 14) 2982 vld1.16 d18, [r9, :64] // in19 (offset 9) 2983 vld1.16 d19, [r7, :64] // in13 (offset 6) 2984 vst1_if d7, [r10, :64], \clear 2985 vst1_if d7, [r11, :64], \clear 2986 vst1_if d7, [r9, :64], \clear 2987 vst1_if d7, [r7, :64], \clear 2988 scale_if \scale, d0[0], q8, q9 2989 bl inv_dct64_step1_neon 2990 2991 sub r6, r6, #2*4*32 2992 add r9, r6, #2*4*7 2993 2994 bl inv_dct64_step2_neon 2995 2996 pop {r10-r11,pc} 2997endfunc 2998.endm 2999 3000def_dct64_func 3001def_dct64_func _clear, clear=1 3002def_dct64_func _clear_scale, clear=1, scale=1 3003 3004function inv_txfm_horz_dct_64x4_neon 3005 vdup.16 q3, r9 3006 3007 mov r7, sp 3008 add r8, sp, #2*4*(64 - 4) 3009 add r9, r6, #2*56 3010 3011 push {r10-r11,lr} 3012 3013 mov r10, #2*64 3014 mov r11, #-2*4*4 3015 30161: 3017 vld1.16 {d16, d17, d18, d19}, [r7, :128]! 3018 vld1.16 {d28, d29, d30, d31}, [r8, :128], r11 3019 vld1.16 {d20, d21, d22, d23}, [r7, :128]! 3020 vld1.16 {d24, d25, d26, d27}, [r8, :128], r11 3021 transpose_4x4h q8, q9, d16, d17, d18, d19 3022 transpose_4x4h q15, q14, d31, d30, d29, d28 3023 transpose_4x4h q10, q11, d20, d21, d22, d23 3024 transpose_4x4h q13, q12, d27, d26, d25, d24 3025 3026.macro store_addsub src0, src1, src2, src3 3027 vqsub.s16 d3, \src0, \src1 3028 vqsub.s16 d2, \src2, \src3 3029 vqadd.s16 d0, \src0, \src1 3030 vqadd.s16 d1, \src2, \src3 3031 vrshl.s16 q1, q1, q3 3032 vrshl.s16 q0, q0, q3 3033 vrev64.16 q1, q1 3034 vst1.16 {q0}, [r6, :128], r10 3035 vst1.16 {q1}, [r9, :128], r10 3036.endm 3037 store_addsub d16, d31, d20, d27 3038 store_addsub d17, d30, d21, d26 3039 store_addsub d18, d29, d22, d25 3040 store_addsub d19, d28, d23, d24 3041.purgem store_addsub 3042 sub r6, r6, r10, lsl #2 3043 sub r9, r9, r10, lsl #2 3044 add r6, r6, #16 3045 sub r9, r9, #16 3046 3047 cmp r7, r8 3048 blt 1b 3049 pop {r10-r11,pc} 3050endfunc 3051 3052function inv_txfm_add_vert_dct_4x64_neon 3053 lsl r8, r8, #1 3054 3055 mov r7, sp 3056 add r8, sp, #2*4*(64 - 4) 3057 add r9, r6, r1, lsl #6 3058 sub r9, r9, r1 3059 3060 push {r10-r11,lr} 3061 3062 neg r10, r1 3063 mov r11, #-2*4*4 3064 30651: 3066 vld1.16 {d16, d17, d18, d19}, [r7, :128]! 3067 vld1.16 {d28, d29, d30, d31}, [r8, :128], r11 3068 vld1.16 {d20, d21, d22, d23}, [r7, :128]! 3069 vld1.16 {d24, d25, d26, d27}, [r8, :128], r11 3070 3071.macro add_dest_addsub src0, src1, src2, src3 3072 vld1.32 {d0[0]}, [r6, :32], r1 3073 vld1.32 {d1[0]}, [r9, :32], r10 3074 vqadd.s16 d4, \src0, \src1 3075 vld1.32 {d0[1]}, [r6, :32] 3076 vqadd.s16 d5, \src2, \src3 3077 vld1.32 {d1[1]}, [r9, :32] 3078 vqsub.s16 d6, \src0, \src1 3079 vqsub.s16 d7, \src2, \src3 3080 sub r6, r6, r1 3081 sub r9, r9, r10 3082 vrshr.s16 q2, q2, #4 3083 vrshr.s16 q3, q3, #4 3084 vaddw.u8 q2, q2, d0 3085 vaddw.u8 q3, q3, d1 3086 vqmovun.s16 d0, q2 3087 vqmovun.s16 d1, q3 3088 vst1.32 {d0[0]}, [r6, :32], r1 3089 vst1.32 {d1[0]}, [r9, :32], r10 3090 vst1.32 {d0[1]}, [r6, :32], r1 3091 vst1.32 {d1[1]}, [r9, :32], r10 3092.endm 3093 add_dest_addsub d16, d31, d17, d30 3094 add_dest_addsub d18, d29, d19, d28 3095 add_dest_addsub d20, d27, d21, d26 3096 add_dest_addsub d22, d25, d23, d24 3097.purgem add_dest_addsub 3098 cmp r7, r8 3099 blt 1b 3100 3101 pop {r10-r11,pc} 3102endfunc 3103 3104function inv_txfm_add_dct_dct_64x64_8bpc_neon, export=1 3105 idct_dc 64, 64, 2 3106 3107 push {r4-r11,lr} 3108 vpush {q4} 3109 3110 sub_sp_align 64*32*2+64*4*2 3111 add r5, sp, #64*4*2 3112 3113 movrel_local r10, eob_32x32 3114 3115.irp i, 0, 4, 8, 12, 16, 20, 24, 28 3116 add r6, r5, #(\i*64*2) 3117.if \i > 0 3118 mov r8, #(32 - \i) 3119 cmp r3, r11 3120 blt 1f 3121.endif 3122 add r7, r2, #(\i*2) 3123 mov r8, #32*2 3124 bl inv_txfm_dct_clear_4h_x64_neon 3125 add r6, r5, #(\i*64*2) 3126 mov r9, #-2 // shift 3127 bl inv_txfm_horz_dct_64x4_neon 3128.if \i < 28 3129 ldrh r11, [r10], #2 3130.endif 3131.endr 3132 b 3f 3133 31341: 3135 vmov.i16 q2, #0 3136 vmov.i16 q3, #0 31372: 3138 subs r8, r8, #2 3139.rept 8 3140 vst1.16 {q2, q3}, [r6, :128]! 3141.endr 3142 bgt 2b 3143 31443: 3145.irp i, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 3146 add r7, r5, #(\i*2) 3147 mov r8, #64*2 3148 bl inv_txfm_dct_4h_x64_neon 3149 add r6, r0, #(\i) 3150 bl inv_txfm_add_vert_dct_4x64_neon 3151.endr 3152 3153 add_sp_align 64*32*2+64*4*2 3154 vpop {q4} 3155 pop {r4-r11,pc} 3156endfunc 3157 3158function inv_txfm_add_dct_dct_64x32_8bpc_neon, export=1 3159 idct_dc 64, 32, 1 3160 3161 push {r4-r11,lr} 3162 vpush {q4} 3163 3164 sub_sp_align 64*32*2+64*4*2 3165 add r5, sp, #64*4*2 3166 3167 movrel_local r10, eob_32x32 3168 3169.irp i, 0, 4, 8, 12, 16, 20, 24, 28 3170 add r6, r5, #(\i*64*2) 3171.if \i > 0 3172 mov r8, #(32 - \i) 3173 cmp r3, r11 3174 blt 1f 3175.endif 3176 add r7, r2, #(\i*2) 3177 mov r8, #32*2 3178 bl inv_txfm_dct_clear_scale_4h_x64_neon 3179 add r6, r5, #(\i*64*2) 3180 mov r9, #-1 // shift 3181 bl inv_txfm_horz_dct_64x4_neon 3182.if \i < 28 3183 ldrh r11, [r10], #2 3184.endif 3185.endr 3186 b 3f 3187 31881: 3189 vmov.i16 q2, #0 3190 vmov.i16 q3, #0 31912: 3192 subs r8, r8, #2 3193.rept 8 3194 vst1.16 {q2, q3}, [r6, :128]! 3195.endr 3196 bgt 2b 3197 31983: 3199.irp i, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 3200 add r6, r0, #(\i) 3201 add r7, r5, #(\i*2) 3202 mov r8, #64*2 3203 bl inv_txfm_add_vert_dct_4x32_neon 3204.endr 3205 3206 add_sp_align 64*32*2+64*4*2 3207 vpop {q4} 3208 pop {r4-r11,pc} 3209endfunc 3210 3211function inv_txfm_add_dct_dct_32x64_8bpc_neon, export=1 3212 idct_dc 32, 64, 1 3213 3214 push {r4-r11,lr} 3215 vpush {q4} 3216 3217 sub_sp_align 32*32*2+64*4*2 3218 add r5, sp, #64*4*2 3219 3220 movrel_local r10, eob_32x32 3221 ldrh r11, [r10], #2 3222 3223.irp i, 0, 4, 8, 12, 16, 20, 24, 28 3224 add r6, r5, #(\i*32*2) 3225.if \i > 0 3226 mov r8, #(32 - \i) 3227 cmp r3, r11 3228 blt 1f 3229.if \i < 28 3230 ldrh r11, [r10], #2 3231.endif 3232.endif 3233 add r7, r2, #(\i*2) 3234 mov r8, #32*2 3235 bl inv_txfm_horz_scale_dct_32x4_neon 3236.endr 3237 b 3f 3238 32391: 3240 vmov.i16 q2, #0 3241 vmov.i16 q3, #0 32422: 3243 subs r8, r8, #2 3244.rept 4 3245 vst1.16 {q2, q3}, [r6, :128]! 3246.endr 3247 bgt 2b 3248 32493: 3250.irp i, 0, 4, 8, 12, 16, 20, 24, 28 3251 add r7, r5, #(\i*2) 3252 mov r8, #32*2 3253 bl inv_txfm_dct_4h_x64_neon 3254 add r6, r0, #(\i) 3255 bl inv_txfm_add_vert_dct_4x64_neon 3256.endr 3257 3258 add_sp_align 32*32*2+64*4*2 3259 vpop {q4} 3260 pop {r4-r11,pc} 3261endfunc 3262 3263function inv_txfm_add_dct_dct_64x16_8bpc_neon, export=1 3264 idct_dc 64, 16, 2 3265 3266 push {r4-r11,lr} 3267 vpush {q4} 3268 3269 sub_sp_align 64*16*2+64*4*2 3270 add r4, sp, #64*4*2 3271 3272 movrel_local r10, eob_16x32 3273 3274.irp i, 0, 4, 8, 12 3275 add r6, r4, #(\i*64*2) 3276.if \i > 0 3277 mov r8, #(16 - \i) 3278 cmp r3, r11 3279 blt 1f 3280.endif 3281 add r7, r2, #(\i*2) 3282 mov r8, #16*2 3283 bl inv_txfm_dct_clear_4h_x64_neon 3284 add r6, r4, #(\i*64*2) 3285 mov r9, #-2 // shift 3286 bl inv_txfm_horz_dct_64x4_neon 3287.if \i < 12 3288 ldrh r11, [r10], #2 3289.endif 3290.endr 3291 b 3f 3292 32931: 3294 vmov.i16 q2, #0 3295 vmov.i16 q3, #0 32962: 3297 subs r8, r8, #2 3298.rept 8 3299 vst1.16 {q2, q3}, [r6, :128]! 3300.endr 3301 bgt 2b 3302 33033: 3304 movrel_local r5, inv_dct_4h_x16_neon 3305.irp i, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60 3306 add r6, r0, #(\i) 3307 add r7, r4, #(\i*2) 3308 mov r8, #64*2 3309 bl inv_txfm_add_vert_4x16_neon 3310.endr 3311 3312 add_sp_align 64*16*2+64*4*2 3313 vpop {q4} 3314 pop {r4-r11,pc} 3315endfunc 3316 3317function inv_txfm_add_dct_dct_16x64_8bpc_neon, export=1 3318 idct_dc 16, 64, 2 3319 3320 push {r4-r11,lr} 3321 vpush {q4} 3322 3323 sub_sp_align 16*32*2+64*4*2 3324 add r5, sp, #64*4*2 3325 3326 movrel_local r10, eob_16x32 3327 ldrh r11, [r10], #2 3328 3329 movrel_local r4, inv_dct_4h_x16_neon 3330.irp i, 0, 4, 8, 12, 16, 20, 24, 28 3331 add r6, r5, #(\i*16*2) 3332.if \i > 0 3333 mov r8, #(32 - \i) 3334 cmp r3, r11 3335 blt 1f 3336.if \i < 28 3337 ldrh r11, [r10], #2 3338.endif 3339.endif 3340 add r7, r2, #(\i*2) 3341 mov r8, #32*2 3342 bl inv_txfm_horz_16x4_neon 3343.endr 3344 b 3f 3345 33461: 3347 vmov.i16 q2, #0 3348 vmov.i16 q3, #0 33492: 3350 subs r8, r8, #4 3351.rept 4 3352 vst1.16 {q2, q3}, [r6, :128]! 3353.endr 3354 bgt 2b 3355 33563: 3357.irp i, 0, 4, 8, 12 3358 add r7, r5, #(\i*2) 3359 mov r8, #16*2 3360 bl inv_txfm_dct_4h_x64_neon 3361 add r6, r0, #(\i) 3362 bl inv_txfm_add_vert_dct_4x64_neon 3363.endr 3364 3365 add_sp_align 16*32*2+64*4*2 3366 vpop {q4} 3367 pop {r4-r11,pc} 3368endfunc 3369