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