tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

itx.S (114899B)


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