tor-browser

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

vp9itxfm_16bpp_neon.S (70099B)


      1 /*
      2 * Copyright (c) 2017 Google Inc.
      3 *
      4 * This file is part of FFmpeg.
      5 *
      6 * FFmpeg is free software; you can redistribute it and/or
      7 * modify it under the terms of the GNU Lesser General Public
      8 * License as published by the Free Software Foundation; either
      9 * version 2.1 of the License, or (at your option) any later version.
     10 *
     11 * FFmpeg is distributed in the hope that it will be useful,
     12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14 * Lesser General Public License for more details.
     15 *
     16 * You should have received a copy of the GNU Lesser General Public
     17 * License along with FFmpeg; if not, write to the Free Software
     18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
     19 */
     20 
     21 #include "libavutil/arm/asm.S"
     22 #include "neon.S"
     23 
     24 const itxfm4_coeffs, align=4
     25        .short  11585, 0, 6270, 15137
     26 iadst4_coeffs:
     27        .short  5283, 15212, 9929, 13377
     28 endconst
     29 
     30 const iadst8_coeffs, align=4
     31        .short  16305, 1606, 14449, 7723, 10394, 12665, 4756, 15679
     32 idct_coeffs:
     33        .short  11585, 0, 6270, 15137, 3196, 16069, 13623, 9102
     34        .short  1606, 16305, 12665, 10394, 7723, 14449, 15679, 4756
     35        .short  804, 16364, 12140, 11003, 7005, 14811, 15426, 5520
     36        .short  3981, 15893, 14053, 8423, 9760, 13160, 16207, 2404
     37 endconst
     38 
     39 const iadst16_coeffs, align=4
     40        .short  16364, 804, 15893, 3981, 11003, 12140, 8423, 14053
     41        .short  14811, 7005, 13160, 9760, 5520, 15426, 2404, 16207
     42 endconst
     43 
     44 @ Do two 4x4 transposes, using q registers for the subtransposes that don't
     45 @ need to address the individual d registers.
     46 @ r0,r1 == rq1, r2,r3 == rq1, etc
     47 .macro transpose32_q_2x_4x4 rq0, rq1, rq2, rq3, rq4, rq5, rq6, rq7, r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15
     48        vswp             \r1,  \r4  @ vtrn.64 \rq0, \rq2
     49        vswp             \r3,  \r6  @ vtrn.64 \rq1, \rq3
     50        vswp             \r9,  \r12 @ vtrn.64 \rq4, \rq6
     51        vswp             \r11, \r14 @ vtrn.64 \rq5, \rq7
     52        vtrn.32          \rq0, \rq1
     53        vtrn.32          \rq2, \rq3
     54        vtrn.32          \rq4, \rq5
     55        vtrn.32          \rq6, \rq7
     56 .endm
     57 
     58 @ Do eight 2x2 transposes.
     59 .macro transpose32_8x_2x2 r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15
     60        vtrn.32          \r0,  \r1
     61        vtrn.32          \r2,  \r3
     62        vtrn.32          \r4,  \r5
     63        vtrn.32          \r6,  \r7
     64        vtrn.32          \r8,  \r9
     65        vtrn.32          \r10, \r11
     66        vtrn.32          \r12, \r13
     67        vtrn.32          \r14, \r15
     68 .endm
     69 
     70 @ out1 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
     71 @ out2 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
     72 @ in/out are d registers
     73 .macro mbutterfly0 out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4, neg=0
     74        vadd.s32        \tmpd1, \in1,  \in2
     75        vsub.s32        \tmpd2, \in1,  \in2
     76 .if \neg > 0
     77        vneg.s32        \tmpd1, \tmpd1
     78 .endif
     79        vmull.s32       \tmpq3, \tmpd1, d0[0]
     80        vmull.s32       \tmpq4, \tmpd2, d0[0]
     81        vrshrn.s64      \out1, \tmpq3, #14
     82        vrshrn.s64      \out2, \tmpq4, #14
     83 .endm
     84 
     85 @ Same as mbutterfly0 above, but treating the input in in2 as zero,
     86 @ writing the same output into both out1 and out2.
     87 .macro mbutterfly0_h out1, out2, in1, in2, tmpd1, tmpd2, tmpq3, tmpq4
     88        vmull.s32       \tmpq3, \in1, d0[0]
     89        vrshrn.s64      \out1, \tmpq3, #14
     90        vrshrn.s64      \out2, \tmpq3, #14
     91 .endm
     92 
     93 @ out1,out2 = ((in1 + in2) * d0[0] + (1 << 13)) >> 14
     94 @ out3,out4 = ((in1 - in2) * d0[0] + (1 << 13)) >> 14
     95 @ Same as mbutterfly0, but with input being 2 q registers, output
     96 @ being 4 d registers.
     97 @ This can do with either 4 or 6 temporary q registers.
     98 .macro dmbutterfly0 out1, out2, out3, out4, in1, in2, tmpq1, tmpq2, tmpd11, tmpd12, tmpd21, tmpd22, tmpq3, tmpq4, tmpq5, tmpq6
     99        vadd.s32        \tmpq1, \in1,  \in2
    100        vsub.s32        \tmpq2, \in1,  \in2
    101        vmull.s32       \tmpq3, \tmpd11, d0[0]
    102        vmull.s32       \tmpq4, \tmpd12, d0[0]
    103 .ifb \tmpq5
    104        vrshrn.s64      \out1, \tmpq3, #14
    105        vrshrn.s64      \out2, \tmpq4, #14
    106        vmull.s32       \tmpq3, \tmpd21, d0[0]
    107        vmull.s32       \tmpq4, \tmpd22, d0[0]
    108        vrshrn.s64      \out3, \tmpq3, #14
    109        vrshrn.s64      \out4, \tmpq4, #14
    110 .else
    111        vmull.s32       \tmpq5, \tmpd21, d0[0]
    112        vmull.s32       \tmpq6, \tmpd22, d0[0]
    113        vrshrn.s64      \out1, \tmpq3, #14
    114        vrshrn.s64      \out2, \tmpq4, #14
    115        vrshrn.s64      \out3, \tmpq5, #14
    116        vrshrn.s64      \out4, \tmpq6, #14
    117 .endif
    118 .endm
    119 
    120 @ out1 = in1 * coef1 - in2 * coef2
    121 @ out2 = in1 * coef2 + in2 * coef1
    122 @ out are 2 q registers, in are 2 d registers
    123 .macro mbutterfly_l out1, out2, in1, in2, coef1, coef2, neg=0
    124        vmull.s32       \out1, \in1, \coef1
    125        vmlsl.s32       \out1, \in2, \coef2
    126 .if \neg
    127        vmov.s64        \out2, #0
    128        vmlsl.s32       \out2, \in1, \coef2
    129        vmlsl.s32       \out2, \in2, \coef1
    130 .else
    131        vmull.s32       \out2, \in1, \coef2
    132        vmlal.s32       \out2, \in2, \coef1
    133 .endif
    134 .endm
    135 
    136 @ out1,out2 = in1,in2 * coef1 - in3,in4 * coef2
    137 @ out3,out4 = in1,in2 * coef2 + in3,in4 * coef1
    138 @ out are 4 q registers, in are 4 d registers
    139 .macro dmbutterfly_l out1, out2, out3, out4, in1, in2, in3, in4, coef1, coef2
    140        vmull.s32       \out1, \in1, \coef1
    141        vmull.s32       \out2, \in2, \coef1
    142        vmull.s32       \out3, \in1, \coef2
    143        vmull.s32       \out4, \in2, \coef2
    144        vmlsl.s32       \out1, \in3, \coef2
    145        vmlsl.s32       \out2, \in4, \coef2
    146        vmlal.s32       \out3, \in3, \coef1
    147        vmlal.s32       \out4, \in4, \coef1
    148 .endm
    149 
    150 @ inout1 = (inout1 * coef1 - inout2 * coef2 + (1 << 13)) >> 14
    151 @ inout2 = (inout1 * coef2 + inout2 * coef1 + (1 << 13)) >> 14
    152 @ inout are 2 d registers, tmp are 2 q registers
    153 .macro mbutterfly inout1, inout2, coef1, coef2, tmp1, tmp2, neg=0
    154        mbutterfly_l    \tmp1, \tmp2, \inout1, \inout2, \coef1, \coef2, \neg
    155        vrshrn.s64      \inout1, \tmp1,  #14
    156        vrshrn.s64      \inout2, \tmp2,  #14
    157 .endm
    158 
    159 @ Same as mbutterfly above, but treating the input in inout2 as zero
    160 .macro mbutterfly_h1 inout1, inout2, coef1, coef2, tmp1, tmp2
    161        vmull.s32       \tmp1,   \inout1, \coef1
    162        vmull.s32       \tmp2,   \inout1, \coef2
    163        vrshrn.s64      \inout1, \tmp1,   #14
    164        vrshrn.s64      \inout2, \tmp2,   #14
    165 .endm
    166 
    167 @ Same as mbutterfly above, but treating the input in inout1 as zero
    168 .macro mbutterfly_h2 inout1, inout2, coef1, coef2, tmp1, tmp2
    169        vmov.s64        \tmp1,   #0
    170        vmull.s32       \tmp2,   \inout2, \coef1
    171        vmlsl.s32       \tmp1,   \inout2, \coef2
    172        vrshrn.s64      \inout2, \tmp2,   #14
    173        vrshrn.s64      \inout1, \tmp1,   #14
    174 .endm
    175 
    176 @ inout1,inout2 = (inout1,inout2 * coef1 - inout3,inout4 * coef2 + (1 << 13)) >> 14
    177 @ inout3,inout4 = (inout1,inout2 * coef2 + inout3,inout4 * coef1 + (1 << 13)) >> 14
    178 @ inout are 4 d registers, tmp are 4 q registers
    179 .macro dmbutterfly inout1, inout2, inout3, inout4, coef1, coef2, tmp1, tmp2, tmp3, tmp4
    180        dmbutterfly_l   \tmp1, \tmp2, \tmp3, \tmp4, \inout1, \inout2, \inout3, \inout4, \coef1, \coef2
    181        vrshrn.s64      \inout1, \tmp1,  #14
    182        vrshrn.s64      \inout2, \tmp2,  #14
    183        vrshrn.s64      \inout3, \tmp3,  #14
    184        vrshrn.s64      \inout4, \tmp4,  #14
    185 .endm
    186 
    187 @ out1 = in1 + in2
    188 @ out2 = in1 - in2
    189 .macro butterfly out1, out2, in1, in2
    190        vadd.s32        \out1, \in1, \in2
    191        vsub.s32        \out2, \in1, \in2
    192 .endm
    193 
    194 @ out1 = in1 - in2
    195 @ out2 = in1 + in2
    196 .macro butterfly_r out1, out2, in1, in2
    197        vsub.s32        \out1, \in1, \in2
    198        vadd.s32        \out2, \in1, \in2
    199 .endm
    200 
    201 @ out1 = (in1 + in2 + (1 << 13)) >> 14
    202 @ out2 = (in1 - in2 + (1 << 13)) >> 14
    203 @ out are 2 d registers, in are 2 q registers, tmp are 2 q registers
    204 .macro butterfly_n out1, out2, in1, in2, tmp1, tmp2
    205        vadd.s64        \tmp1, \in1, \in2
    206        vsub.s64        \tmp2, \in1, \in2
    207        vrshrn.s64      \out1, \tmp1,  #14
    208        vrshrn.s64      \out2, \tmp2,  #14
    209 .endm
    210 
    211 @ out1,out2 = (in1,in2 + in3,in4 + (1 << 13)) >> 14
    212 @ out3,out4 = (in1,in2 - in3,in4 + (1 << 13)) >> 14
    213 @ out are 4 d registers, in are 4 q registers, tmp are 4 q registers
    214 .macro dbutterfly_n out1, out2, out3, out4, in1, in2, in3, in4, tmp1, tmp2, tmp3, tmp4
    215        vadd.s64        \tmp1, \in1, \in3
    216        vadd.s64        \tmp2, \in2, \in4
    217        vsub.s64        \tmp3, \in1, \in3
    218        vsub.s64        \tmp4, \in2, \in4
    219        vrshrn.s64      \out1, \tmp1,  #14
    220        vrshrn.s64      \out2, \tmp2,  #14
    221        vrshrn.s64      \out3, \tmp3,  #14
    222        vrshrn.s64      \out4, \tmp4,  #14
    223 .endm
    224 
    225 
    226 .macro iwht4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
    227        vadd.i32        \c0,  \c0,  \c1
    228        vsub.i32        q11,  \c2,  \c3
    229        vsub.i32        q10,  \c0,  q11
    230        vshr.s32        q10,  q10,  #1
    231        vsub.i32        \c2,  q10,  \c1
    232        vsub.i32        \c1,  q10,  \c3
    233        vadd.i32        \c3,  q11,  \c2
    234        vsub.i32        \c0,  \c0,  \c1
    235 .endm
    236 
    237 .macro iwht4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
    238        iwht4_10        \c0, \c1, \c2, \c3, \cd0, \cd1, \cd2, \cd3, \cd4, \cd5, \cd6, \cd7
    239 .endm
    240 
    241 @ c0 == cd0,cd1, c1 == cd2,cd3
    242 .macro idct4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
    243        vmul.s32        q13,  \c1,  d1[1]
    244        vmul.s32        q11,  \c1,  d1[0]
    245        vadd.i32        q14,  \c0,  \c2
    246        vsub.i32        q15,  \c0,  \c2
    247        vmla.s32        q13,  \c3,  d1[0]
    248        vmul.s32        q12,  q14,  d0[0]
    249        vmul.s32        q10,  q15,  d0[0]
    250        vmls.s32        q11,  \c3,  d1[1]
    251        vrshr.s32       q13,  q13,  #14
    252        vrshr.s32       q12,  q12,  #14
    253        vrshr.s32       q10,  q10,  #14
    254        vrshr.s32       q11,  q11,  #14
    255        vadd.i32        \c0,  q12,  q13
    256        vsub.i32        \c3,  q12,  q13
    257        vadd.i32        \c1,  q10,  q11
    258        vsub.i32        \c2,  q10,  q11
    259 .endm
    260 
    261 .macro idct4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
    262        vmull.s32       q13,  \cd2, d1[1]
    263        vmull.s32       q15,  \cd3, d1[1]
    264        vmull.s32       q11,  \cd2, d1[0]
    265        vmull.s32       q3,   \cd3, d1[0]
    266        vadd.i32        q14,  \c0,  \c2
    267        vsub.i32        q2,   \c0,  \c2
    268        vmlal.s32       q13,  \cd6, d1[0]
    269        vmlal.s32       q15,  \cd7, d1[0]
    270        vmull.s32       q12,  d28,  d0[0]
    271        vmull.s32       q14,  d29,  d0[0]
    272        vmull.s32       q10,  d4,   d0[0]
    273        vmull.s32       q8,   d5,   d0[0]
    274        vmlsl.s32       q11,  \cd6, d1[1]
    275        vmlsl.s32       q3,   \cd7, d1[1]
    276        vrshrn.s64      d26,  q13,  #14
    277        vrshrn.s64      d27,  q15,  #14
    278        vrshrn.s64      d24,  q12,  #14
    279        vrshrn.s64      d25,  q14,  #14
    280        vrshrn.s64      d20,  q10,  #14
    281        vrshrn.s64      d21,  q8,   #14
    282        vrshrn.s64      d22,  q11,  #14
    283        vrshrn.s64      d23,  q3,   #14
    284        vadd.i32        \c0,  q12,  q13
    285        vsub.i32        \c3,  q12,  q13
    286        vadd.i32        \c1,  q10,  q11
    287        vsub.i32        \c2,  q10,  q11
    288 .endm
    289 
    290 .macro iadst4_10 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
    291        vmul.s32        q10,  \c0,  d2[0]
    292        vmla.s32        q10,  \c2,  d2[1]
    293        vmla.s32        q10,  \c3,  d3[0]
    294        vmul.s32        q11,  \c0,  d3[0]
    295        vmls.s32        q11,  \c2,  d2[0]
    296        vsub.s32        \c0,  \c0,  \c2
    297        vmls.s32        q11,  \c3,  d2[1]
    298        vadd.s32        \c0,  \c0,  \c3
    299        vmul.s32        q13,  \c1,  d3[1]
    300        vmul.s32        q12,  \c0,  d3[1]
    301        vadd.s32        q14,  q10,  q13
    302        vadd.s32        q15,  q11,  q13
    303        vrshr.s32       \c0,  q14,  #14
    304        vadd.s32        q10,  q10,  q11
    305        vrshr.s32       \c1,  q15,  #14
    306        vsub.s32        q10,  q10,  q13
    307        vrshr.s32       \c2,  q12,  #14
    308        vrshr.s32       \c3,  q10,  #14
    309 .endm
    310 
    311 .macro iadst4_12 c0, c1, c2, c3, cd0, cd1, cd2, cd3, cd4, cd5, cd6, cd7
    312        vmull.s32       q10,  \cd0, d2[0]
    313        vmull.s32       q4,   \cd1, d2[0]
    314        vmlal.s32       q10,  \cd4, d2[1]
    315        vmlal.s32       q4,   \cd5, d2[1]
    316        vmlal.s32       q10,  \cd6, d3[0]
    317        vmlal.s32       q4,   \cd7, d3[0]
    318        vmull.s32       q11,  \cd0, d3[0]
    319        vmull.s32       q5,   \cd1, d3[0]
    320        vmlsl.s32       q11,  \cd4, d2[0]
    321        vmlsl.s32       q5,   \cd5, d2[0]
    322        vsub.s32        \c0,  \c0,  \c2
    323        vmlsl.s32       q11,  \cd6, d2[1]
    324        vmlsl.s32       q5,   \cd7, d2[1]
    325        vadd.s32        \c0,  \c0,  \c3
    326        vmull.s32       q13,  \cd2, d3[1]
    327        vmull.s32       q6,   \cd3, d3[1]
    328        vmull.s32       q12,  \cd0, d3[1]
    329        vmull.s32       q7,   \cd1, d3[1]
    330        vadd.s64        q14,  q10,  q13
    331        vadd.s64        q2,   q4,   q6
    332        vadd.s64        q15,  q11,  q13
    333        vadd.s64        q3,   q5,   q6
    334        vrshrn.s64      \cd1, q2,   #14
    335        vrshrn.s64      \cd0, q14,  #14
    336        vadd.s64        q10,  q10,  q11
    337        vadd.s64        q4,   q4,   q5
    338        vrshrn.s64      \cd3, q3,   #14
    339        vrshrn.s64      \cd2, q15,  #14
    340        vsub.s64        q10,  q10,  q13
    341        vsub.s64        q4,   q4,   q6
    342        vrshrn.s64      \cd4, q12,  #14
    343        vrshrn.s64      \cd5, q7,   #14
    344        vrshrn.s64      \cd6, q10,  #14
    345        vrshrn.s64      \cd7, q4,   #14
    346 .endm
    347 
    348 @ The public functions in this file have got the following signature:
    349 @ void itxfm_add(uint8_t *dst, ptrdiff_t stride, int16_t *block, int eob);
    350 
    351 .macro itxfm_func4x4 txfm1, txfm2, bpp
    352 function ff_vp9_\txfm1\()_\txfm2\()_4x4_add_\bpp\()_neon, export=1
    353 .ifc \txfm1,\txfm2
    354 .ifc \txfm1,idct
    355        movrel          r12, itxfm4_coeffs
    356        vld1.16         {d0}, [r12,:64]
    357        vmovl.s16       q0,  d0
    358 .endif
    359 .ifc \txfm1,iadst
    360        movrel          r12, iadst4_coeffs
    361        vld1.16         {d1}, [r12,:64]
    362        vmovl.s16       q1,  d1
    363 .endif
    364 .else
    365        movrel          r12, itxfm4_coeffs
    366        vld1.16         {q0}, [r12,:128]
    367        vmovl.s16       q1,  d1
    368        vmovl.s16       q0,  d0
    369 .endif
    370 .if \bpp > 10
    371 .ifnc \txfm1\()_\txfm2,idct_idct
    372        @ iadst4_12 needs q4-q7
    373        vpush           {q4-q7}
    374 .endif
    375 .endif
    376 
    377        vmov.i32        q14, #0
    378        vmov.i32        q15, #0
    379 .ifc \txfm1\()_\txfm2,idct_idct
    380        cmp             r3,  #1
    381        bne             1f
    382        @ DC-only for idct/idct
    383        vld1.32         {d4[]},   [r2,:32]
    384        vmull.s32       q2,  d4,  d0[0]
    385        vrshrn.s64      d4,  q2,  #14
    386        vmull.s32       q2,  d4,  d0[0]
    387        vrshrn.s64      d4,  q2,  #14
    388        vst1.32         {d30[0]}, [r2,:32]
    389        vdup.32         q2,  d4[0]
    390        vmov            q3,  q2
    391        vmov            q8,  q2
    392        vmov            q9,  q2
    393        b               2f
    394 .endif
    395 
    396 1:
    397        vld1.32         {q2-q3},   [r2,:128]
    398        vst1.32         {q14-q15}, [r2,:128]!
    399        vld1.32         {q8-q9},   [r2,:128]
    400 
    401 .ifc \txfm1,iwht
    402        vshr.s32        q2,  q2,  #2
    403        vshr.s32        q3,  q3,  #2
    404        vshr.s32        q8,  q8,  #2
    405        vshr.s32        q9,  q9,  #2
    406 .endif
    407 
    408        vst1.16         {q14-q15}, [r2,:128]!
    409        \txfm1\()4_\bpp q2,  q3,  q8,  q9,  d4,  d5,  d6,  d7,  d16, d17, d18, d19
    410 
    411        @ Transpose 4x4 with 32 bit elements
    412        vtrn.32         q2,  q3
    413        vtrn.32         q8,  q9
    414        vswp            d5,  d16
    415        vswp            d7,  d18
    416 
    417        \txfm2\()4_\bpp q2,  q3,  q8,  q9,  d4,  d5,  d6,  d7,  d16, d17, d18, d19
    418 2:
    419        vmvn.u16        q15, #((0xffff << \bpp) & 0xffff)
    420        vld1.16         {d0},  [r0,:64], r1
    421        vld1.16         {d1},  [r0,:64], r1
    422 .ifnc \txfm1,iwht
    423        vrshr.s32       q2,  q2,  #4
    424        vrshr.s32       q3,  q3,  #4
    425        vrshr.s32       q8,  q8,  #4
    426        vrshr.s32       q9,  q9,  #4
    427 .endif
    428        vaddw.u16       q2,  q2,  d0
    429        vaddw.u16       q3,  q3,  d1
    430        vld1.16         {d2},  [r0,:64], r1
    431        vld1.16         {d3},  [r0,:64], r1
    432        vqmovun.s32     d0,  q2
    433        vqmovun.s32     d1,  q3
    434        sub             r0,  r0,  r1, lsl #2
    435 
    436        vaddw.u16       q8,  q8,  d2
    437        vmin.u16        q0,  q0,  q15
    438        vaddw.u16       q9,  q9,  d3
    439        vst1.16         {d0},  [r0,:64], r1
    440        vqmovun.s32     d2,  q8
    441        vqmovun.s32     d3,  q9
    442        vmin.u16        q1,  q1,  q15
    443 
    444        vst1.16         {d1},  [r0,:64], r1
    445        vst1.16         {d2},  [r0,:64], r1
    446        vst1.16         {d3},  [r0,:64], r1
    447 
    448 .if \bpp > 10
    449 .ifnc \txfm1\()_\txfm2,idct_idct
    450        vpop            {q4-q7}
    451 .endif
    452 .endif
    453        bx              lr
    454 endfunc
    455 .endm
    456 
    457 .macro itxfm_funcs4x4 bpp
    458 itxfm_func4x4 idct,  idct,  \bpp
    459 itxfm_func4x4 iadst, idct,  \bpp
    460 itxfm_func4x4 idct,  iadst, \bpp
    461 itxfm_func4x4 iadst, iadst, \bpp
    462 itxfm_func4x4 iwht,  iwht,  \bpp
    463 .endm
    464 
    465 itxfm_funcs4x4 10
    466 itxfm_funcs4x4 12
    467 
    468 .macro idct8
    469        dmbutterfly0    d16, d17, d24, d25, q8,  q12, q2, q4, d4, d5, d8, d9, q3, q2, q5, q4 @ q8 = t0a, q12 = t1a
    470        dmbutterfly     d20, d21, d28, d29, d1[0], d1[1], q2,  q3,  q4,  q5 @ q10 = t2a, q14 = t3a
    471        dmbutterfly     d18, d19, d30, d31, d2[0], d2[1], q2,  q3,  q4,  q5 @ q9  = t4a, q15 = t7a
    472        dmbutterfly     d26, d27, d22, d23, d3[0], d3[1], q2,  q3,  q4,  q5 @ q13 = t5a, q11 = t6a
    473 
    474        butterfly       q2,  q14, q8,  q14 @ q2 = t0, q14 = t3
    475        butterfly       q3,  q10, q12, q10 @ q3 = t1, q10 = t2
    476        butterfly       q4,  q13, q9,  q13 @ q4 = t4, q13 = t5a
    477        butterfly       q5,  q11, q15, q11 @ q5 = t7, q11 = t6a
    478 
    479        butterfly       q8,  q15, q2,  q5  @ q8 = out[0], q15 = out[7]
    480 
    481        dmbutterfly0    d4,  d5,  d10, d11, q11, q13, q9,  q13, d18, d19, d26, d27, q2,  q5, q11, q12 @ q2 = t6, q5 = t5
    482 
    483        butterfly       q11, q12, q14, q4  @ q11 = out[3], q12 = out[4]
    484        butterfly       q9,  q14, q3,  q2  @ q9 = out[1],  q14 = out[6]
    485        butterfly_r     q13, q10, q10, q5  @ q13 = out[5], q10 = out[2]
    486 .endm
    487 
    488 .macro iadst8
    489        movrel          r12, iadst8_coeffs
    490        vld1.16         {q1}, [r12,:128]!
    491        vmovl.s16       q0,  d2
    492        vmovl.s16       q1,  d3
    493 
    494        dmbutterfly_l   q4,  q5,  q2,  q3,  d30, d31, d16, d17, d0[1], d0[0] @ q4,q5  = t1a, q2,q3 = t0a
    495        dmbutterfly_l   q8,  q15, q6,  q7,  d22, d23, d24, d25, d2[1], d2[0] @ q8,q15 = t5a, q6,q7 = t4a
    496 
    497        dbutterfly_n    d22, d23, d4,  d5,  q2,  q3,  q6,  q7,  q11, q12, q2,  q3 @ q11 = t0, q2 = t4
    498 
    499        dbutterfly_n    d24, d25, d6,  d7,  q4,  q5,  q8,  q15, q12, q3,  q6,  q7 @ q12 = t1, q3 = t5
    500 
    501        dmbutterfly_l   q6,  q7,  q4,  q5,  d26, d27, d20, d21, d1[1], d1[0] @ q6,q7 = t3a, q4,q5 = t2a
    502        dmbutterfly_l   q10, q13, q8,  q15, d18, d19, d28, d29, d3[1], d3[0] @ q10,q13 = t7a, q8,q15 = t6a
    503 
    504        dbutterfly_n    d18, d19, d8,  d9,  q4,  q5,  q8,  q15, q9,  q14, q4, q5 @ q9 = t2, q4 = t6
    505        dbutterfly_n    d16, d17, d12, d13, q6,  q7,  q10, q13, q8,  q15, q6, q7 @ q8 = t3, q6 = t7
    506 
    507        movrel          r12, idct_coeffs
    508        vld1.16         {q0}, [r12,:128]
    509        vmovl.s16       q1,  d1
    510        vmovl.s16       q0,  d0
    511 
    512        butterfly       q15, q12, q12, q8 @ q15 = -out[7], q12 = t3
    513        vneg.s32        q15, q15          @ q15 = out[7]
    514        butterfly       q8,  q9,  q11, q9 @ q8 = out[0], q9 = t2
    515 
    516        dmbutterfly_l   q10, q11, q5,  q7,  d4,  d5,  d6,  d7,  d1[0], d1[1] @ q10,q11 = t5a, q5,q7 = t4a
    517        dmbutterfly_l   q2,  q3,  q13, q14, d12, d13, d8,  d9,  d1[1], d1[0] @ q2,q3 = t6a, q13,q14 = t7a
    518 
    519        dbutterfly_n    d28, d29, d8,  d9,  q10, q11, q13, q14, q4,  q6,  q10, q11 @ q14 = out[6], q4 = t7
    520 
    521        dmbutterfly0    d22, d23, d24, d25, q9,  q12, q6, q13, d12, d13, d26, d27, q9, q10 @ q11 = -out[3], q12 = out[4]
    522        vneg.s32        q11, q11      @ q11 = out[3]
    523 
    524        dbutterfly_n    d18, d19, d4,  d5,  q5,  q7,  q2,  q3,  q9, q10, q2,  q3 @ q9 = -out[1], q2 = t6
    525        vneg.s32        q9,  q9       @ q9 = out[1]
    526 
    527        dmbutterfly0    d20, d21, d26, d27, q2,  q4,  q3, q5,  d6,  d7,  d10, d11, q6,  q7 @ q10 = out[2], q13 = -out[5]
    528        vneg.s32        q13, q13      @ q13 = out[5]
    529 .endm
    530 
    531 function idct8x8_dc_add_neon
    532        movrel          r12, idct_coeffs
    533        vld1.16         {d0}, [r12,:64]
    534 
    535        vmov.i32        q2,  #0
    536        vmovl.s16       q0,  d0
    537 
    538        vld1.32         {d16[]}, [r2,:32]
    539        vmull.s32       q8,  d16, d0[0]
    540        vrshrn.s64      d16, q8,  #14
    541        vmull.s32       q8,  d16, d0[0]
    542        vrshrn.s64      d16, q8,  #14
    543        vdup.32         q8,  d16[0]
    544        vst1.32         {d4[0]}, [r2,:32]
    545 
    546        vrshr.s32       q8,  q8,  #5
    547        vdup.s16        q15, r8
    548 
    549        mov             r3,  r0
    550        mov             r12, #8
    551 1:
    552        @ Loop to add the constant from q8 into all 8x8 outputs
    553        subs            r12, r12, #2
    554        vld1.16         {q2},  [r0,:128], r1
    555        vaddw.u16       q10, q8,  d4
    556        vld1.16         {q3},  [r0,:128], r1
    557        vaddw.u16       q11, q8,  d5
    558        vaddw.u16       q12, q8,  d6
    559        vaddw.u16       q13, q8,  d7
    560        vqmovun.s32     d4,  q10
    561        vqmovun.s32     d5,  q11
    562        vqmovun.s32     d6,  q12
    563        vqmovun.s32     d7,  q13
    564        vmin.u16        q2,  q2,  q15
    565        vst1.16         {q2},  [r3,:128], r1
    566        vmin.u16        q3,  q3,  q15
    567        vst1.16         {q3},  [r3,:128], r1
    568        bne             1b
    569 
    570        pop             {r4-r8,pc}
    571 endfunc
    572 .ltorg
    573 
    574 .macro itxfm8_1d_funcs txfm
    575 @ Read a vertical 4x8 slice out of a 8x8 matrix, do a transform on it,
    576 @ transpose into a horizontal 8x4 slice and store.
    577 @ r0 = dst (temp buffer)
    578 @ r1 = slice offset
    579 @ r2 = src
    580 function \txfm\()8_1d_4x8_pass1_neon
    581        mov             r12, #32
    582        vmov.s32        q2,  #0
    583 .irp i, 8, 9, 10, 11, 12, 13, 14, 15
    584        vld1.32         {q\i}, [r2,:128]
    585        vst1.32         {q2},  [r2,:128], r12
    586 .endr
    587 
    588        \txfm\()8
    589 
    590        @ Do two 4x4 transposes. Originally, q8-q15 contain the
    591        @ 8 rows. Afterwards, q8-q11, q12-q15 contain the transposed
    592        @ 4x4 blocks.
    593        transpose32_q_2x_4x4 q8,  q9,  q10, q11, q12, q13, q14, q15, d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
    594 
    595        @ Store the transposed 4x4 blocks horizontally.
    596        cmp             r1,  #4
    597        beq             1f
    598 .irp i, 8, 12, 9, 13, 10, 14, 11, 15
    599        vst1.32         {q\i}, [r0,:128]!
    600 .endr
    601        bx              lr
    602 1:
    603        @ Special case: For the last input column (r1 == 4),
    604        @ which would be stored as the last row in the temp buffer,
    605        @ don't store the first 4x4 block, but keep it in registers
    606        @ for the first slice of the second pass (where it is the
    607        @ last 4x4 block).
    608 .irp i, 12, 13, 14, 15
    609        add             r0,  r0,  #16
    610        vst1.32         {q\i}, [r0,:128]!
    611 .endr
    612        vmov            q12, q8
    613        vmov            q13, q9
    614        vmov            q14, q10
    615        vmov            q15, q11
    616        bx              lr
    617 endfunc
    618 
    619 @ Read a vertical 4x8 slice out of a 8x8 matrix, do a transform on it,
    620 @ load the destination pixels (from a similar 4x8 slice), add and store back.
    621 @ r0 = dst
    622 @ r1 = dst stride
    623 @ r2 = src (temp buffer)
    624 @ r3 = slice offset
    625 function \txfm\()8_1d_4x8_pass2_neon
    626        mov             r12, #32
    627 .irp i, 8, 9, 10, 11
    628        vld1.32         {q\i}, [r2,:128], r12
    629 .endr
    630        cmp             r3,  #0
    631        beq             1f
    632 .irp i, 12, 13, 14, 15
    633        vld1.32         {q\i}, [r2,:128], r12
    634 .endr
    635 1:
    636 
    637        add             r3,  r0,  r1
    638        lsl             r1,  r1,  #1
    639        \txfm\()8
    640 
    641        vdup.s16        q4,  r8
    642 .macro load_add_store coef0, coef1, coef2, coef3
    643        vld1.16         {d4},   [r0,:64], r1
    644        vld1.16         {d5},   [r3,:64], r1
    645        vld1.16         {d6},   [r0,:64], r1
    646        vld1.16         {d7},   [r3,:64], r1
    647 
    648        vrshr.s32       \coef0, \coef0, #5
    649        vrshr.s32       \coef1, \coef1, #5
    650        vrshr.s32       \coef2, \coef2, #5
    651        vrshr.s32       \coef3, \coef3, #5
    652 
    653        vaddw.u16       \coef0, \coef0, d4
    654        vaddw.u16       \coef1, \coef1, d5
    655        vaddw.u16       \coef2, \coef2, d6
    656        vaddw.u16       \coef3, \coef3, d7
    657 
    658        sub             r0,  r0,  r1, lsl #1
    659        sub             r3,  r3,  r1, lsl #1
    660 
    661        vqmovun.s32     d4,  \coef0
    662        vqmovun.s32     d5,  \coef1
    663        vqmovun.s32     d6,  \coef2
    664        vqmovun.s32     d7,  \coef3
    665 
    666        vmin.u16        q2,  q2,  q4
    667        vmin.u16        q3,  q3,  q4
    668 
    669        vst1.16         {d4},  [r0,:64], r1
    670        vst1.16         {d5},  [r3,:64], r1
    671        vst1.16         {d6},  [r0,:64], r1
    672        vst1.16         {d7},  [r3,:64], r1
    673 .endm
    674        load_add_store  q8,  q9,  q10, q11
    675        load_add_store  q12, q13, q14, q15
    676 .purgem load_add_store
    677 
    678        bx              lr
    679 endfunc
    680 .endm
    681 
    682 itxfm8_1d_funcs idct
    683 itxfm8_1d_funcs iadst
    684 
    685 .macro itxfm_func8x8 txfm1, txfm2
    686 function vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
    687 .ifc \txfm1\()_\txfm2,idct_idct
    688        cmp             r3,  #1
    689        beq             idct8x8_dc_add_neon
    690 .endif
    691 .ifnc \txfm1\()_\txfm2,idct_idct
    692        vpush           {q4-q7}
    693 .else
    694        vpush           {q4-q5}
    695 .endif
    696 
    697        @ Align the stack, allocate a temp buffer
    698 T       mov             r7,  sp
    699 T       and             r7,  r7,  #15
    700 A       and             r7,  sp,  #15
    701        add             r7,  r7,  #256
    702        sub             sp,  sp,  r7
    703 
    704        mov             r4,  r0
    705        mov             r5,  r1
    706        mov             r6,  r2
    707 
    708 .ifc \txfm1,idct
    709        movrel          r12, idct_coeffs
    710        vld1.16         {q0}, [r12,:128]
    711        vmovl.s16       q1,  d1
    712        vmovl.s16       q0,  d0
    713 .endif
    714 
    715 .irp i, 0, 4
    716        add             r0,  sp,  #(\i*32)
    717 .ifc \txfm1\()_\txfm2,idct_idct
    718 .if \i == 4
    719        cmp             r3,  #12
    720        ble             1f
    721 .endif
    722 .endif
    723        mov             r1,  #\i
    724        add             r2,  r6,  #(\i*4)
    725        bl              \txfm1\()8_1d_4x8_pass1_neon
    726 .endr
    727 .ifc \txfm1\()_\txfm2,idct_idct
    728        b               3f
    729 1:
    730        @ For all-zero slices in pass 1, set q12-q15 to zero, for the in-register
    731        @ passthrough of coefficients to pass 2 and clear the end of the temp buffer
    732        vmov.i32        q12, #0
    733        vmov.i32        q13, #0
    734        vmov.i32        q14, #0
    735        vmov.i32        q15, #0
    736 .rept 4
    737        vst1.32         {q12-q13}, [r0,:128]!
    738 .endr
    739 3:
    740 .endif
    741 .ifc \txfm1\()_\txfm2,iadst_idct
    742        movrel          r12, idct_coeffs
    743        vld1.16         {q0}, [r12,:128]
    744        vmovl.s16       q1,  d1
    745        vmovl.s16       q0,  d0
    746 .endif
    747 .irp i, 0, 4
    748        add             r0,  r4,  #(\i*2)
    749        mov             r1,  r5
    750        add             r2,  sp,  #(\i*4)
    751        mov             r3,  #\i
    752        bl              \txfm2\()8_1d_4x8_pass2_neon
    753 .endr
    754 
    755        add             sp,  sp,  r7
    756 .ifnc \txfm1\()_\txfm2,idct_idct
    757        vpop            {q4-q7}
    758 .else
    759        vpop            {q4-q5}
    760 .endif
    761        pop             {r4-r8,pc}
    762 endfunc
    763 
    764 function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_10_neon, export=1
    765        push            {r4-r8,lr}
    766        movw            r8,  #0x03ff
    767        b               vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
    768 endfunc
    769 
    770 function ff_vp9_\txfm1\()_\txfm2\()_8x8_add_12_neon, export=1
    771        push            {r4-r8,lr}
    772        movw            r8,  #0x0fff
    773        b               vp9_\txfm1\()_\txfm2\()_8x8_add_16_neon
    774 endfunc
    775 .endm
    776 
    777 itxfm_func8x8 idct,  idct
    778 itxfm_func8x8 iadst, idct
    779 itxfm_func8x8 idct,  iadst
    780 itxfm_func8x8 iadst, iadst
    781 
    782 function idct16x16_dc_add_neon
    783        movrel          r12, idct_coeffs
    784        vld1.16         {d0}, [r12,:64]
    785 
    786        vmov.i32        q2,  #0
    787        vmovl.s16       q0,  d0
    788 
    789        vld1.32         {d16[]}, [r2,:32]
    790        vmull.s32       q8,  d16, d0[0]
    791        vrshrn.s64      d16, q8,  #14
    792        vmull.s32       q8,  d16, d0[0]
    793        vrshrn.s64      d16, q8,  #14
    794        vdup.32         q8,  d16[0]
    795        vst1.32         {d4[0]}, [r2,:32]
    796 
    797        vrshr.s32       q8,  q8,  #6
    798        vdup.s16        q15, r9
    799 
    800        mov             r3,  r0
    801        mov             r12, #16
    802 1:
    803        @ Loop to add the constant from q8 into all 16x16 outputs
    804        subs            r12, r12, #2
    805        vld1.16         {q0-q1},  [r0,:128], r1
    806        vaddw.u16       q9,  q8,  d0
    807        vaddw.u16       q10, q8,  d1
    808        vld1.16         {q2-q3},  [r0,:128], r1
    809        vaddw.u16       q11, q8,  d2
    810        vaddw.u16       q12, q8,  d3
    811        vaddw.u16       q13, q8,  d4
    812        vaddw.u16       q14, q8,  d5
    813        vqmovun.s32     d0,  q9
    814        vaddw.u16       q9,  q8,  d6
    815        vqmovun.s32     d1,  q10
    816        vaddw.u16       q10, q8,  d7
    817        vqmovun.s32     d2,  q11
    818        vqmovun.s32     d3,  q12
    819        vqmovun.s32     d4,  q13
    820        vqmovun.s32     d5,  q14
    821        vmin.u16        q0,  q0,  q15
    822        vmin.u16        q1,  q1,  q15
    823        vqmovun.s32     d6,  q9
    824        vqmovun.s32     d7,  q10
    825        vst1.16         {q0-q1},  [r3,:128], r1
    826        vmin.u16        q2,  q2,  q15
    827        vmin.u16        q3,  q3,  q15
    828        vst1.16         {q2-q3},  [r3,:128], r1
    829        bne             1b
    830 
    831        pop             {r4-r9,pc}
    832 endfunc
    833 .ltorg
    834 
    835 .macro idct16_end
    836        butterfly       d18, d11, d8,  d11               @ d18 = t0a,  d11 = t7a
    837        butterfly       d19, d22, d9,  d22               @ d19 = t1a,  d22 = t6
    838        butterfly       d8,  d26, d20, d26               @ d8  = t2a,  d26 = t5
    839        butterfly       d9,  d10, d28, d10               @ d9  = t3a,  d10 = t4
    840        butterfly       d20, d28, d16, d24               @ d20 = t8a,  d28 = t11a
    841        butterfly       d24, d21, d23, d21               @ d24 = t9,   d21 = t10
    842        butterfly       d23, d27, d25, d27               @ d23 = t14,  d27 = t13
    843        butterfly       d25, d29, d29, d17               @ d25 = t15a, d29 = t12a
    844 
    845        mbutterfly0     d27, d21, d27, d21, d16, d30, q8, q15 @ d27 = t13a, d21 = t10a
    846        mbutterfly0     d29, d28, d29, d28, d16, d30, q8, q15 @ d29 = t12,  d28 = t11
    847 
    848        vswp            d27, d29                         @ d27 = t12, d29 = t13a
    849        vswp            d28, d27                         @ d28 = t12, d27 = t11
    850        butterfly       d16, d31, d18, d25               @ d16 = out[0], d31 = out[15]
    851        butterfly       d17, d30, d19, d23               @ d17 = out[1], d30 = out[14]
    852        butterfly_r     d25, d22, d22, d24               @ d25 = out[9], d22 = out[6]
    853        butterfly       d23, d24, d11, d20               @ d23 = out[7], d24 = out[8]
    854        butterfly       d18, d29, d8,  d29               @ d18 = out[2], d29 = out[13]
    855        butterfly       d19, d28, d9,  d28               @ d19 = out[3], d28 = out[12]
    856        vmov            d8,  d21                         @ d8  = t10a
    857        butterfly       d20, d27, d10, d27               @ d20 = out[4], d27 = out[11]
    858        butterfly       d21, d26, d26, d8                @ d21 = out[5], d26 = out[10]
    859        bx              lr
    860 .endm
    861 
    862 function idct16
    863        mbutterfly0     d16, d24, d16, d24, d8, d10, q4,  q5 @ d16 = t0a,  d24 = t1a
    864        mbutterfly      d20, d28, d1[0], d1[1], q4,  q5  @ d20 = t2a,  d28 = t3a
    865        mbutterfly      d18, d30, d2[0], d2[1], q4,  q5  @ d18 = t4a,  d30 = t7a
    866        mbutterfly      d26, d22, d3[0], d3[1], q4,  q5  @ d26 = t5a,  d22 = t6a
    867        mbutterfly      d17, d31, d4[0], d4[1], q4,  q5  @ d17 = t8a,  d31 = t15a
    868        mbutterfly      d25, d23, d5[0], d5[1], q4,  q5  @ d25 = t9a,  d23 = t14a
    869        mbutterfly      d21, d27, d6[0], d6[1], q4,  q5  @ d21 = t10a, d27 = t13a
    870        mbutterfly      d29, d19, d7[0], d7[1], q4,  q5  @ d29 = t11a, d19 = t12a
    871 
    872        butterfly       d8,  d28, d16, d28               @ d8  = t0,   d28 = t3
    873        butterfly       d9,  d20, d24, d20               @ d9  = t1,   d20 = t2
    874        butterfly       d10, d26, d18, d26               @ d10 = t4,   d26 = t5
    875        butterfly       d11, d22, d30, d22               @ d11 = t7,   d22 = t6
    876        butterfly       d16, d25, d17, d25               @ d16 = t8,   d25 = t9
    877        butterfly       d24, d21, d29, d21               @ d24 = t11,  d21 = t10
    878        butterfly       d17, d27, d19, d27               @ d17 = t12,  d27 = t13
    879        butterfly       d29, d23, d31, d23               @ d29 = t15,  d23 = t14
    880 
    881        mbutterfly0     d22, d26, d22, d26, d18, d30, q9,  q15  @ d22 = t6a, d26 = t5a
    882        mbutterfly      d23, d25, d1[0], d1[1], q9,  q15        @ d23 = t9a,  d25 = t14a
    883        mbutterfly      d27, d21, d1[0], d1[1], q9,  q15, neg=1 @ d27 = t13a, d21 = t10a
    884        idct16_end
    885 endfunc
    886 
    887 function idct16_half
    888        mbutterfly0_h   d16, d24, d16, d24, d8, d10, q4,  q5 @ d16 = t0a,  d24 = t1a
    889        mbutterfly_h1   d20, d28, d1[0], d1[1], q4,  q5  @ d20 = t2a,  d28 = t3a
    890        mbutterfly_h1   d18, d30, d2[0], d2[1], q4,  q5  @ d18 = t4a,  d30 = t7a
    891        mbutterfly_h2   d26, d22, d3[0], d3[1], q4,  q5  @ d26 = t5a,  d22 = t6a
    892        mbutterfly_h1   d17, d31, d4[0], d4[1], q4,  q5  @ d17 = t8a,  d31 = t15a
    893        mbutterfly_h2   d25, d23, d5[0], d5[1], q4,  q5  @ d25 = t9a,  d23 = t14a
    894        mbutterfly_h1   d21, d27, d6[0], d6[1], q4,  q5  @ d21 = t10a, d27 = t13a
    895        mbutterfly_h2   d29, d19, d7[0], d7[1], q4,  q5  @ d29 = t11a, d19 = t12a
    896 
    897        butterfly       d8,  d28, d16, d28               @ d8  = t0,   d28 = t3
    898        butterfly       d9,  d20, d24, d20               @ d9  = t1,   d20 = t2
    899        butterfly       d10, d26, d18, d26               @ d10 = t4,   d26 = t5
    900        butterfly       d11, d22, d30, d22               @ d11 = t7,   d22 = t6
    901        butterfly       d16, d25, d17, d25               @ d16 = t8,   d25 = t9
    902        butterfly       d24, d21, d29, d21               @ d24 = t11,  d21 = t10
    903        butterfly       d17, d27, d19, d27               @ d17 = t12,  d27 = t13
    904        butterfly       d29, d23, d31, d23               @ d29 = t15,  d23 = t14
    905 
    906        mbutterfly0     d22, d26, d22, d26, d18, d30, q9,  q15  @ d22 = t6a, d26 = t5a
    907        mbutterfly      d23, d25, d1[0], d1[1], q9,  q15        @ d23 = t9a,  d25 = t14a
    908        mbutterfly      d27, d21, d1[0], d1[1], q9,  q15, neg=1 @ d27 = t13a, d21 = t10a
    909        idct16_end
    910 endfunc
    911 
    912 function idct16_quarter
    913        vmov.s64        q12, #0
    914        vmull.s32       q4,  d17, d4[0]
    915        vmull.s32       q5,  d18, d2[1]
    916        vmull.s32       q15, d18, d2[0]
    917        vmlsl.s32       q12, d19, d7[1]
    918        vmull.s32       q14, d17, d4[1]
    919        vmull.s32       q13, d19, d7[0]
    920        vmull.s32       q11, d16, d0[0]
    921        vrshrn.s64      d16, q4,  #14
    922        vrshrn.s64      d11, q5,  #14
    923        vrshrn.s64      d10, q15, #14
    924        vrshrn.s64      d24, q12, #14
    925        vrshrn.s64      d29, q14, #14
    926        vrshrn.s64      d17, q13, #14
    927        vrshrn.s64      d28, q11, #14
    928 
    929        mbutterfly_l    q10, q11, d17, d24, d1[0], d1[1], neg=1
    930        mbutterfly_l    q9,  q15, d29, d16, d1[0], d1[1]
    931        vrshrn.s64      d27, q10, #14
    932        vrshrn.s64      d21, q11, #14
    933        vrshrn.s64      d23, q9,  #14
    934        vrshrn.s64      d25, q15, #14
    935        vmov            d8,  d28
    936        vmov            d9,  d28
    937        mbutterfly0     d22, d26, d11, d10, d18, d30, q9,  q15
    938        vmov            d20, d28
    939        idct16_end
    940 endfunc
    941 
    942 function iadst16
    943        movrel          r12, iadst16_coeffs
    944        vld1.16         {q0},  [r12,:128]!
    945        vmovl.s16       q1,  d1
    946        vmovl.s16       q0,  d0
    947 
    948        mbutterfly_l    q3,  q2,  d31, d16, d0[1], d0[0] @ q3  = t1,   q2  = t0
    949        mbutterfly_l    q5,  q4,  d23, d24, d2[1], d2[0] @ q5  = t9,   q4  = t8
    950        butterfly_n     d31, d24, q3,  q5,  q6,  q5      @ d31 = t1a,  d24 = t9a
    951        mbutterfly_l    q7,  q6,  d29, d18, d1[1], d1[0] @ q7  = t3,   q6  = t2
    952        butterfly_n     d16, d23, q2,  q4,  q3,  q4      @ d16 = t0a,  d23 = t8a
    953        mbutterfly_l    q3,  q2,  d21, d26, d3[1], d3[0] @ q3  = t11,  q2  = t10
    954 
    955        vld1.16         {q0},  [r12,:128]!
    956        butterfly_n     d29, d26, q7,  q3,  q4,  q3      @ d29 = t3a,  d26 = t11a
    957        vmovl.s16       q1,  d1
    958        vmovl.s16       q0,  d0
    959        mbutterfly_l    q5,  q4,  d27, d20, d0[1], d0[0] @ q5  = t5,   q4  = t4
    960        butterfly_n     d18, d21, q6,  q2,  q3,  q2      @ d18 = t2a,  d21 = t10a
    961 
    962        mbutterfly_l    q7,  q6,  d19, d28, d2[1], d2[0] @ q7  = t13,  q6  = t12
    963        butterfly_n     d20, d28, q5,  q7,  q2,  q7      @ d20 = t5a,  d28 = t13a
    964        mbutterfly_l    q3,  q2,  d25, d22, d1[1], d1[0] @ q3  = t7,   q2  = t6
    965        butterfly_n     d27, d19, q4,  q6,  q5,  q6      @ d27 = t4a,  d19 = t12a
    966 
    967        mbutterfly_l    q5,  q4,  d17, d30, d3[1], d3[0] @ q5  = t15,  q4  = t14
    968        movrel          r12, idct_coeffs
    969        vld1.16         {q0}, [r12,:128]
    970        vmovl.s16       q1,  d1
    971        vmovl.s16       q0,  d0
    972        butterfly_n     d22, d30, q3,  q5,  q6,  q5      @ d22 = t7a,  d30 = t15a
    973        mbutterfly_l    q7,  q6,  d23, d24, d2[0], d2[1] @ q7  = t9,   q6  = t8
    974        butterfly_n     d25, d17, q2,  q4,  q3,  q4      @ d25 = t6a,  d17 = t14a
    975 
    976        mbutterfly_l    q2,  q3,  d28, d19, d2[1], d2[0] @ q2  = t12,  q3  = t13
    977        butterfly_n     d23, d19, q6,  q2,  q4,  q2      @ d23 = t8a,  d19 = t12a
    978        mbutterfly_l    q5,  q4,  d21, d26, d3[0], d3[1] @ q5  = t11,  q4  = t10
    979        butterfly_r     d4,  d27, d16, d27               @ d4  = t4,   d27 = t0
    980        butterfly_n     d24, d28, q7,  q3,  q6,  q3      @ d24 = t9a,  d28 = t13a
    981 
    982        mbutterfly_l    q6,  q7,  d30, d17, d3[1], d3[0] @ q6  = t14,  q7  = t15
    983        butterfly_r     d5,  d20, d31, d20               @ d5  = t5,   d20 = t1
    984        butterfly_n     d21, d17, q4,  q6,  q3,  q6      @ d21 = t10a, d17 = t14a
    985        butterfly_n     d26, d30, q5,  q7,  q4,  q7      @ d26 = t11a, d30 = t15a
    986 
    987        butterfly_r     d6,  d25, d18, d25               @ d6  = t6,   d25 = t2
    988        butterfly_r     d7,  d22, d29, d22               @ d7  = t7,   d22 = t3
    989 
    990        mbutterfly_l    q5,  q4,  d19, d28, d1[0], d1[1] @ q5  = t13,  q4  = t12
    991        mbutterfly_l    q6,  q7,  d30, d17, d1[1], d1[0] @ q6  = t14,  q7  = t15
    992 
    993        butterfly_n     d18, d30, q4,  q6,  q8,  q6      @ d18 = out[2],   d30 = t14a
    994        butterfly_n     d29, d17, q5,  q7,  q6,  q7      @ d29 = -out[13], d17 = t15a
    995        vneg.s32        d29, d29                         @ d29 = out[13]
    996 
    997        mbutterfly_l    q5,  q4,  d4,  d5,  d1[0], d1[1] @ q5  = t5a,  q4  = t4a
    998        mbutterfly_l    q6,  q7,  d7,  d6,  d1[1], d1[0] @ q6  = t6a,  q7  = t7a
    999 
   1000        butterfly       d2,  d6,  d27, d25               @ d2 = out[0], d6 = t2a
   1001        butterfly       d3,  d7,  d23, d21               @ d3 =-out[1], d7 = t10
   1002 
   1003        butterfly_n     d19, d31, q4,  q6,  q2,  q4      @ d19 = -out[3],  d31 = t6
   1004        vneg.s32        d19, d19                         @ d19 = out[3]
   1005        butterfly_n     d28, d16, q5,  q7,  q2,  q5      @ d28 = out[12],  d16 = t7
   1006 
   1007        butterfly       d5,  d8,  d20, d22               @ d5 =-out[15],d8 = t3a
   1008        butterfly       d4,  d9,  d24, d26               @ d4 = out[14],d9 = t11
   1009 
   1010        mbutterfly0     d23, d24, d6,  d8,  d10, d11, q6,  q7, 1 @ d23 = out[7], d24 = out[8]
   1011        mbutterfly0     d20, d27, d16, d31, d10, d11, q6,  q7    @ d20 = out[4], d27 = out[11]
   1012        mbutterfly0     d22, d25, d9,  d7,  d10, d11, q6,  q7    @ d22 = out[6], d25 = out[9]
   1013        mbutterfly0     d21, d26, d30, d17, d10, d11, q6,  q7, 1 @ d21 = out[5], d26 = out[10]
   1014 
   1015        vneg.s32        d31, d5                          @ d31 = out[15]
   1016        vneg.s32        d17, d3                          @ d17 = out[1]
   1017 
   1018        vmov            d16, d2
   1019        vmov            d30, d4
   1020        bx              lr
   1021 endfunc
   1022 
   1023 .macro itxfm16_1d_funcs txfm, suffix
   1024 @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it,
   1025 @ transpose into a horizontal 16x2 slice and store.
   1026 @ r0 = dst (temp buffer)
   1027 @ r2 = src
   1028 function \txfm\()16_1d_2x16_pass1\suffix\()_neon
   1029        push            {lr}
   1030 
   1031        mov             r12, #64
   1032        vmov.s32        q4,  #0
   1033 .ifb \suffix
   1034 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
   1035        vld1.32         {d\i}, [r2,:64]
   1036        vst1.32         {d8},  [r2,:64], r12
   1037 .endr
   1038 .endif
   1039 .ifc \suffix,_quarter
   1040 .irp i, 16, 17, 18, 19
   1041        vld1.32         {d\i}, [r2,:64]
   1042        vst1.32         {d8},  [r2,:64], r12
   1043 .endr
   1044 .endif
   1045 .ifc \suffix,_half
   1046 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
   1047        vld1.32         {d\i}, [r2,:64]
   1048        vst1.32         {d8},  [r2,:64], r12
   1049 .endr
   1050 .endif
   1051 
   1052        bl              \txfm\()16\suffix
   1053 
   1054        @ Do eight 2x2 transposes. Originally, d16-d31 contain the
   1055        @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight
   1056        @ transposed 2x2 blocks.
   1057        transpose32_8x_2x2 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
   1058 
   1059        @ Store the transposed 2x2 blocks horizontally.
   1060 .irp i, 16, 18, 20, 22, 24, 26, 28, 30, 17, 19, 21, 23, 25, 27, 29, 31
   1061        vst1.32         {d\i}, [r0,:64]!
   1062 .endr
   1063        pop             {pc}
   1064 endfunc
   1065 
   1066 @ Read a vertical 2x16 slice out of a 16x16 matrix, do a transform on it,
   1067 @ load the destination pixels (from a similar 2x16 slice), add and store back.
   1068 @ r0 = dst
   1069 @ r1 = dst stride
   1070 @ r2 = src (temp buffer)
   1071 function \txfm\()16_1d_2x16_pass2\suffix\()_neon
   1072        push            {lr}
   1073 
   1074        mov             r12, #64
   1075 .ifb \suffix
   1076 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
   1077        vld1.16         {d\i}, [r2,:64], r12
   1078 .endr
   1079 .endif
   1080 .ifc \suffix,_quarter
   1081 .irp i, 16, 17, 18, 19, 20
   1082        vld1.16         {d\i}, [r2,:64], r12
   1083 .endr
   1084 .endif
   1085 .ifc \suffix,_half
   1086 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
   1087        vld1.16         {d\i}, [r2,:64], r12
   1088 .endr
   1089 .endif
   1090 
   1091        add             r3,  r0,  r1
   1092        lsl             r1,  r1,  #1
   1093        bl              \txfm\()16\suffix
   1094 
   1095 .macro load_add_store coef0, coef1, coef2, coef3
   1096        vrshr.s32       \coef0, \coef0, #6
   1097        vrshr.s32       \coef1, \coef1, #6
   1098 
   1099        vld1.32         {d8[]},   [r0,:32], r1
   1100        vld1.32         {d8[1]},  [r3,:32], r1
   1101        vrshr.s32       \coef2, \coef2, #6
   1102        vrshr.s32       \coef3, \coef3, #6
   1103        vld1.32         {d9[]},   [r0,:32], r1
   1104        vld1.32         {d9[1]},  [r3,:32], r1
   1105        vaddw.u16       \coef0, \coef0, d8
   1106        vld1.32         {d10[]},  [r0,:32], r1
   1107        vld1.32         {d10[1]}, [r3,:32], r1
   1108        vaddw.u16       \coef1, \coef1, d9
   1109        vld1.32         {d11[]},  [r0,:32], r1
   1110        vld1.32         {d11[1]}, [r3,:32], r1
   1111 
   1112        vqmovun.s32     d8,  \coef0
   1113        vdup.s16        q8,  r9
   1114        vqmovun.s32     d9,  \coef1
   1115        sub             r0,  r0,  r1, lsl #2
   1116        sub             r3,  r3,  r1, lsl #2
   1117        vaddw.u16       \coef2, \coef2, d10
   1118        vaddw.u16       \coef3, \coef3, d11
   1119        vmin.u16        q4,  q4,  q8
   1120        vst1.32         {d8[0]},  [r0,:32], r1
   1121        vst1.32         {d8[1]},  [r3,:32], r1
   1122        vqmovun.s32     d10, \coef2
   1123        vst1.32         {d9[0]},  [r0,:32], r1
   1124        vst1.32         {d9[1]},  [r3,:32], r1
   1125        vqmovun.s32     d11, \coef3
   1126        vmin.u16        q5,  q5,  q8
   1127 
   1128        vst1.32         {d10[0]}, [r0,:32], r1
   1129        vst1.32         {d10[1]}, [r3,:32], r1
   1130        vst1.32         {d11[0]}, [r0,:32], r1
   1131        vst1.32         {d11[1]}, [r3,:32], r1
   1132 .endm
   1133        load_add_store  q8,  q9,  q10, q11
   1134        load_add_store  q12, q13, q14, q15
   1135 .purgem load_add_store
   1136 
   1137        pop             {pc}
   1138 endfunc
   1139 .endm
   1140 
   1141 itxfm16_1d_funcs idct
   1142 itxfm16_1d_funcs iadst
   1143 itxfm16_1d_funcs idct, _quarter
   1144 itxfm16_1d_funcs idct, _half
   1145 .ltorg
   1146 
   1147 @ This is the minimum eob value for each subpartition, in increments of 2
   1148 const min_eob_idct_idct_16, align=4
   1149        .short  0, 3, 10, 22, 38, 62, 89, 121
   1150 endconst
   1151 
   1152 .macro itxfm_func16x16 txfm1, txfm2
   1153 function vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
   1154 .ifc \txfm1\()_\txfm2,idct_idct
   1155        cmp             r3,  #1
   1156        beq             idct16x16_dc_add_neon
   1157 .endif
   1158 .ifnc \txfm1\()_\txfm2,idct_idct
   1159        vpush           {q4-q7}
   1160 .else
   1161        vpush           {q4-q5}
   1162 .endif
   1163 
   1164        @ Align the stack, allocate a temp buffer
   1165 T       mov             r7,  sp
   1166 T       and             r7,  r7,  #15
   1167 A       and             r7,  sp,  #15
   1168        add             r7,  r7,  #1024
   1169        sub             sp,  sp,  r7
   1170 
   1171        mov             r4,  r0
   1172        mov             r5,  r1
   1173        mov             r6,  r2
   1174 
   1175 .ifc \txfm1,idct
   1176        movrel          r12, idct_coeffs
   1177        vld1.16         {q0-q1}, [r12,:128]
   1178        vmovl.s16       q2,  d2
   1179        vmovl.s16       q3,  d3
   1180        vmovl.s16       q1,  d1
   1181        vmovl.s16       q0,  d0
   1182 .endif
   1183 
   1184 .ifc \txfm1\()_\txfm2,idct_idct
   1185        cmp             r3,  #10
   1186        ble             idct16x16_quarter_add_16_neon
   1187        cmp             r3,  #38
   1188        ble             idct16x16_half_add_16_neon
   1189 
   1190        movrel          r8,  min_eob_idct_idct_16 + 2
   1191 .endif
   1192 
   1193 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
   1194        add             r0,  sp,  #(\i*64)
   1195 .ifc \txfm1\()_\txfm2,idct_idct
   1196 .if \i > 0
   1197        ldrh_post       r1,  r8,  #2
   1198        cmp             r3,  r1
   1199        it              le
   1200        movle           r1,  #(16 - \i)/2
   1201        ble             1f
   1202 .endif
   1203 .endif
   1204        add             r2,  r6,  #(\i*4)
   1205        bl              \txfm1\()16_1d_2x16_pass1_neon
   1206 .endr
   1207 
   1208 .ifc \txfm1\()_\txfm2,idct_idct
   1209        b               3f
   1210 1:
   1211        vmov.i32        q14, #0
   1212        vmov.i32        q15, #0
   1213 2:
   1214        subs            r1,  r1,  #1
   1215        @ Unroll for 2 lines
   1216 .rept 2
   1217        @ Fill one line with zeros
   1218        vst1.32         {q14-q15}, [r0,:128]!
   1219        vst1.32         {q14-q15}, [r0,:128]!
   1220 .endr
   1221        bne             2b
   1222 3:
   1223 .endif
   1224 
   1225 .ifc \txfm1\()_\txfm2,iadst_idct
   1226        movrel          r12, idct_coeffs
   1227        vld1.16         {q0-q1}, [r12,:128]
   1228        vmovl.s16       q2,  d2
   1229        vmovl.s16       q3,  d3
   1230        vmovl.s16       q1,  d1
   1231        vmovl.s16       q0,  d0
   1232 .endif
   1233 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
   1234        add             r0,  r4,  #(\i*2)
   1235        mov             r1,  r5
   1236        add             r2,  sp,  #(\i*4)
   1237        bl              \txfm2\()16_1d_2x16_pass2_neon
   1238 .endr
   1239 
   1240        add             sp,  sp,  r7
   1241 .ifnc \txfm1\()_\txfm2,idct_idct
   1242        vpop            {q4-q7}
   1243 .else
   1244        vpop            {q4-q5}
   1245 .endif
   1246        pop             {r4-r9,pc}
   1247 endfunc
   1248 
   1249 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_10_neon, export=1
   1250        push            {r4-r9,lr}
   1251        movw            r9,  #0x03ff
   1252        b               vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
   1253 endfunc
   1254 
   1255 function ff_vp9_\txfm1\()_\txfm2\()_16x16_add_12_neon, export=1
   1256        push            {r4-r9,lr}
   1257        movw            r9,  #0x0fff
   1258        b               vp9_\txfm1\()_\txfm2\()_16x16_add_16_neon
   1259 endfunc
   1260 .endm
   1261 
   1262 itxfm_func16x16 idct,  idct
   1263 itxfm_func16x16 iadst, idct
   1264 itxfm_func16x16 idct,  iadst
   1265 itxfm_func16x16 iadst, iadst
   1266 .ltorg
   1267 
   1268 .macro idct16_partial size
   1269 function idct16x16_\size\()_add_16_neon
   1270 .irp i, 0, 2
   1271        add             r0,  sp,  #(\i*64)
   1272 .ifc \size,quarter
   1273 .if \i == 2
   1274        cmp             r3,  #3
   1275        ble             1f
   1276 .endif
   1277 .endif
   1278        add             r2,  r6,  #(\i*4)
   1279        bl              idct16_1d_2x16_pass1_\size\()_neon
   1280 .endr
   1281 
   1282 .ifc \size,half
   1283 .irp i, 4, 6
   1284        add             r0,  sp,  #(\i*64)
   1285 .if \i == 6
   1286        cmp             r3,  #22
   1287        ble             1f
   1288 .endif
   1289        add             r2,  r6,  #(\i*4)
   1290        bl              idct16_1d_2x16_pass1_\size\()_neon
   1291 .endr
   1292 .endif
   1293 
   1294        b               3f
   1295 1:
   1296        vmov.i32        q14, #0
   1297        vmov.i32        q15, #0
   1298 
   1299        @ Unroll for 2 lines
   1300 .rept 2
   1301        @ Fill one line with zeros
   1302        vst1.32         {q14-q15}, [r0,:128]!
   1303        vst1.32         {q14-q15}, [r0,:128]!
   1304 .endr
   1305 
   1306 3:
   1307 
   1308 .irp i, 0, 2, 4, 6, 8, 10, 12, 14
   1309        add             r0,  r4,  #(\i*2)
   1310        mov             r1,  r5
   1311        add             r2,  sp,  #(\i*4)
   1312        bl              idct16_1d_2x16_pass2_\size\()_neon
   1313 .endr
   1314 
   1315        add             sp,  sp,  r7
   1316        vpop            {q4-q5}
   1317        pop             {r4-r9,pc}
   1318 endfunc
   1319 .endm
   1320 
   1321 idct16_partial quarter
   1322 idct16_partial half
   1323 
   1324 function idct32x32_dc_add_neon
   1325        movrel          r12, idct_coeffs
   1326        vld1.16         {d0}, [r12,:64]
   1327 
   1328        vmov.i32        q2,  #0
   1329        vmovl.s16       q0,  d0
   1330 
   1331        vld1.32         {d16[]}, [r2,:32]
   1332        vmull.s32       q8,  d16, d0[0]
   1333        vrshrn.s64      d16, q8,  #14
   1334        vmull.s32       q8,  d16, d0[0]
   1335        vrshrn.s64      d16, q8,  #14
   1336        vdup.32         q8,  d16[0]
   1337        vst1.32         {d4[0]}, [r2,:32]
   1338 
   1339        vrshr.s32       q8,  q8,  #6
   1340        vdup.s16        q15, r9
   1341 
   1342        mov             r3,  r0
   1343        mov             r12, #32
   1344        sub             r1,  r1,  #32
   1345 1:
   1346        @ Loop to add the constant from q8 into all 32x32 outputs
   1347        subs            r12, r12, #1
   1348        vld1.16         {q0-q1},  [r0,:128]!
   1349        vaddw.u16       q9,  q8,  d0
   1350        vaddw.u16       q10, q8,  d1
   1351        vld1.16         {q2-q3},  [r0,:128], r1
   1352        vaddw.u16       q11, q8,  d2
   1353        vaddw.u16       q12, q8,  d3
   1354        vaddw.u16       q13, q8,  d4
   1355        vaddw.u16       q14, q8,  d5
   1356        vqmovun.s32     d0,  q9
   1357        vaddw.u16       q9,  q8,  d6
   1358        vqmovun.s32     d1,  q10
   1359        vaddw.u16       q10, q8,  d7
   1360        vqmovun.s32     d2,  q11
   1361        vqmovun.s32     d3,  q12
   1362        vqmovun.s32     d4,  q13
   1363        vqmovun.s32     d5,  q14
   1364        vmin.u16        q0,  q0,  q15
   1365        vmin.u16        q1,  q1,  q15
   1366        vqmovun.s32     d6,  q9
   1367        vqmovun.s32     d7,  q10
   1368        vst1.16         {q0-q1},  [r3,:128]!
   1369        vmin.u16        q2,  q2,  q15
   1370        vmin.u16        q3,  q3,  q15
   1371        vst1.16         {q2-q3},  [r3,:128], r1
   1372        bne             1b
   1373 
   1374        pop             {r4-r9,pc}
   1375 endfunc
   1376 
   1377 .macro idct32_end
   1378        butterfly       d16, d9,  d8,  d9  @ d16 = t16a, d9  = t19a
   1379        butterfly       d17, d20, d23, d20 @ d17 = t17,  d20 = t18
   1380        butterfly       d18, d10, d11, d10 @ d18 = t23a, d10 = t20a
   1381        butterfly       d19, d21, d22, d21 @ d19 = t22,  d21 = t21
   1382        butterfly       d8,  d28, d28, d30 @ d8  = t24a, d28 = t27a
   1383        butterfly       d23, d26, d25, d26 @ d23 = t25,  d26 = t26
   1384        butterfly       d11, d29, d29, d31 @ d11 = t31a, d29 = t28a
   1385        butterfly       d22, d27, d24, d27 @ d22 = t30,  d27 = t29
   1386 
   1387        mbutterfly      d27, d20, d1[0], d1[1], q12, q15        @ d27 = t18a, d20 = t29a
   1388        mbutterfly      d29, d9,  d1[0], d1[1], q12, q15        @ d29 = t19,  d9  = t28
   1389        mbutterfly      d28, d10, d1[0], d1[1], q12, q15, neg=1 @ d28 = t27,  d10 = t20
   1390        mbutterfly      d26, d21, d1[0], d1[1], q12, q15, neg=1 @ d26 = t26a, d21 = t21a
   1391 
   1392        butterfly       d31, d24, d11, d8  @ d31 = t31,  d24 = t24
   1393        butterfly       d30, d25, d22, d23 @ d30 = t30a, d25 = t25a
   1394        butterfly_r     d23, d16, d16, d18 @ d23 = t23,  d16 = t16
   1395        butterfly_r     d22, d17, d17, d19 @ d22 = t22a, d17 = t17a
   1396        butterfly       d18, d21, d27, d21 @ d18 = t18,  d21 = t21
   1397        butterfly_r     d27, d28, d9,  d28 @ d27 = t27a, d28 = t28a
   1398        butterfly       d8,  d26, d20, d26 @ d8  = t29,  d26 = t26
   1399        butterfly       d19, d20, d29, d10 @ d19 = t19a, d20 = t20
   1400        vmov            d29, d8            @ d29 = t29
   1401 
   1402        mbutterfly0     d27, d20, d27, d20, d8, d10, q4, q5 @ d27 = t27,  d20 = t20
   1403        mbutterfly0     d26, d21, d26, d21, d8, d10, q4, q5 @ d26 = t26a, d21 = t21a
   1404        mbutterfly0     d25, d22, d25, d22, d8, d10, q4, q5 @ d25 = t25,  d22 = t22
   1405        mbutterfly0     d24, d23, d24, d23, d8, d10, q4, q5 @ d24 = t24a, d23 = t23a
   1406        bx              lr
   1407 .endm
   1408 
   1409 function idct32_odd
   1410        movrel          r12, idct_coeffs
   1411 
   1412        @ Overwrite the idct16 coeffs with the stored ones for idct32
   1413        vmovl.s16       q0,  d12
   1414        vmovl.s16       q1,  d13
   1415        vmovl.s16       q2,  d14
   1416        vmovl.s16       q3,  d15
   1417 
   1418        mbutterfly      d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a
   1419        mbutterfly      d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a
   1420        mbutterfly      d20, d27, d2[0], d2[1], q4, q5 @ d20 = t18a, d27 = t29a
   1421        mbutterfly      d28, d19, d3[0], d3[1], q4, q5 @ d28 = t19a, d19 = t28a
   1422        mbutterfly      d18, d29, d4[0], d4[1], q4, q5 @ d18 = t20a, d29 = t27a
   1423        mbutterfly      d26, d21, d5[0], d5[1], q4, q5 @ d26 = t21a, d21 = t26a
   1424        mbutterfly      d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a
   1425        mbutterfly      d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a
   1426 
   1427        @ Reload the idct16 coefficients. We could swap the coefficients between
   1428        @ q0-q3 and q6-q7 by narrowing/lengthening, but that's slower than just
   1429        @ loading and lengthening.
   1430        vld1.16         {q0-q1}, [r12,:128]
   1431 
   1432        butterfly       d8,  d24, d16, d24 @ d8  = t16, d24 = t17
   1433        butterfly       d9,  d20, d28, d20 @ d9  = t19, d20 = t18
   1434        butterfly       d10, d26, d18, d26 @ d10 = t20, d26 = t21
   1435        butterfly       d11, d22, d30, d22 @ d11 = t23, d22 = t22
   1436        vmovl.s16       q2,  d2
   1437        vmovl.s16       q3,  d3
   1438        vmovl.s16       q1,  d1
   1439        vmovl.s16       q0,  d0
   1440        butterfly       d28, d25, d17, d25 @ d28 = t24, d25 = t25
   1441        butterfly       d30, d21, d29, d21 @ d30 = t27, d21 = t26
   1442        butterfly       d29, d23, d31, d23 @ d29 = t31, d23 = t30
   1443        butterfly       d31, d27, d19, d27 @ d31 = t28, d27 = t29
   1444 
   1445        mbutterfly      d23, d24, d2[0], d2[1], q8, q9        @ d23 = t17a, d24 = t30a
   1446        mbutterfly      d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
   1447        mbutterfly      d21, d26, d3[0], d3[1], q8, q9        @ d21 = t21a, d26 = t26a
   1448        mbutterfly      d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
   1449        idct32_end
   1450 endfunc
   1451 
   1452 function idct32_odd_half
   1453        movrel          r12, idct_coeffs
   1454 
   1455        vmovl.s16       q0,  d12
   1456        vmovl.s16       q1,  d13
   1457        vmovl.s16       q2,  d14
   1458        vmovl.s16       q3,  d15
   1459 
   1460        mbutterfly_h1   d16, d31, d0[0], d0[1], q4, q5 @ d16 = t16a, d31 = t31a
   1461        mbutterfly_h2   d24, d23, d1[0], d1[1], q4, q5 @ d24 = t17a, d23 = t30a
   1462        mbutterfly_h1   d20, d27, d2[0], d2[1], q4, q5 @ d20 = t18a, d27 = t29a
   1463        mbutterfly_h2   d28, d19, d3[0], d3[1], q4, q5 @ d28 = t19a, d19 = t28a
   1464        mbutterfly_h1   d18, d29, d4[0], d4[1], q4, q5 @ d18 = t20a, d29 = t27a
   1465        mbutterfly_h2   d26, d21, d5[0], d5[1], q4, q5 @ d26 = t21a, d21 = t26a
   1466        mbutterfly_h1   d22, d25, d6[0], d6[1], q4, q5 @ d22 = t22a, d25 = t25a
   1467        mbutterfly_h2   d30, d17, d7[0], d7[1], q4, q5 @ d30 = t23a, d17 = t24a
   1468 
   1469        vld1.16         {q0-q1}, [r12,:128]
   1470 
   1471        butterfly       d8,  d24, d16, d24 @ d8  = t16, d24 = t17
   1472        butterfly       d9,  d20, d28, d20 @ d9  = t19, d20 = t18
   1473        butterfly       d10, d26, d18, d26 @ d10 = t20, d26 = t21
   1474        butterfly       d11, d22, d30, d22 @ d11 = t23, d22 = t22
   1475        vmovl.s16       q2,  d2
   1476        vmovl.s16       q3,  d3
   1477        vmovl.s16       q1,  d1
   1478        vmovl.s16       q0,  d0
   1479        butterfly       d28, d25, d17, d25 @ d28 = t24, d25 = t25
   1480        butterfly       d30, d21, d29, d21 @ d30 = t27, d21 = t26
   1481        butterfly       d29, d23, d31, d23 @ d29 = t31, d23 = t30
   1482        butterfly       d31, d27, d19, d27 @ d31 = t28, d27 = t29
   1483 
   1484        mbutterfly      d23, d24, d2[0], d2[1], q8, q9        @ d23 = t17a, d24 = t30a
   1485        mbutterfly      d27, d20, d2[0], d2[1], q8, q9, neg=1 @ d27 = t29a, d20 = t18a
   1486        mbutterfly      d21, d26, d3[0], d3[1], q8, q9        @ d21 = t21a, d26 = t26a
   1487        mbutterfly      d25, d22, d3[0], d3[1], q8, q9, neg=1 @ d25 = t25a, d22 = t22a
   1488        idct32_end
   1489 endfunc
   1490 
   1491 function idct32_odd_quarter
   1492        movrel          r12, idct_coeffs
   1493 
   1494        vmovl.s16       q0,  d12
   1495        vmovl.s16       q1,  d13
   1496        vmovl.s16       q2,  d14
   1497        vmovl.s16       q3,  d15
   1498 
   1499        vmov.s64        q14, #0
   1500        vmov.s64        q5,  #0
   1501 
   1502        vmull.s32       q4,  d16, d0[0]
   1503        vmlsl.s32       q14, d19, d3[1]
   1504        vmull.s32       q15, d16, d0[1]
   1505        vmull.s32       q11, d17, d7[0]
   1506        vmlsl.s32       q5,  d17, d7[1]
   1507        vmull.s32       q13, d19, d3[0]
   1508        vmull.s32       q10, d18, d4[0]
   1509        vmull.s32       q12, d18, d4[1]
   1510 
   1511        vld1.16         {q0-q1}, [r12,:128]
   1512 
   1513        vrshrn.s64      d8,  q4,  #14
   1514        vrshrn.s64      d9,  q14, #14
   1515        vrshrn.s64      d29, q15, #14
   1516        vrshrn.s64      d28, q11, #14
   1517 
   1518        vmovl.s16       q2,  d2
   1519        vmovl.s16       q3,  d3
   1520        vmovl.s16       q1,  d1
   1521        vmovl.s16       q0,  d0
   1522 
   1523        vrshrn.s64      d11, q5,  #14
   1524        vrshrn.s64      d31, q13, #14
   1525        vrshrn.s64      d10, q10, #14
   1526        vrshrn.s64      d30, q12, #14
   1527 
   1528        mbutterfly_l    q8,  q9,  d29, d8,  d2[0], d2[1]
   1529        mbutterfly_l    q13, q10, d31, d9,  d2[0], d2[1], neg=1
   1530        vrshrn.s64      d23, q8,  #14
   1531        vrshrn.s64      d24, q9,  #14
   1532        vrshrn.s64      d27, q13, #14
   1533        vrshrn.s64      d20, q10, #14
   1534        mbutterfly_l    q8,  q9,  d30, d10, d3[0], d3[1]
   1535        vrshrn.s64      d21, q8,  #14
   1536        vrshrn.s64      d26, q9,  #14
   1537        mbutterfly_l    q8,  q9,  d28, d11, d3[0], d3[1], neg=1
   1538        vrshrn.s64      d25, q8,  #14
   1539        vrshrn.s64      d22, q9,  #14
   1540 
   1541        idct32_end
   1542 endfunc
   1543 
   1544 .macro idct32_funcs suffix
   1545 @ Do an 32-point IDCT of a 2x32 slice out of a 32x32 matrix.
   1546 @ We don't have register space to do a single pass IDCT of 2x32 though,
   1547 @ but the 32-point IDCT can be decomposed into two 16-point IDCTs;
   1548 @ a normal IDCT16 with every other input component (the even ones, with
   1549 @ each output written twice), followed by a separate 16-point IDCT
   1550 @ of the odd inputs, added/subtracted onto the outputs of the first idct16.
   1551 @ r0 = dst (temp buffer)
   1552 @ r1 = unused
   1553 @ r2 = src
   1554 function idct32_1d_2x32_pass1\suffix\()_neon
   1555        push            {lr}
   1556 
   1557        @ Double stride of the input, since we only read every other line
   1558        mov             r12, #256
   1559        vmov.s32        d8,  #0
   1560 
   1561        @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
   1562 .ifb \suffix
   1563 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
   1564        vld1.32         {d\i}, [r2,:64]
   1565        vst1.32         {d8},  [r2,:64], r12
   1566 .endr
   1567 .endif
   1568 .ifc \suffix,_quarter
   1569 .irp i, 16, 17, 18, 19
   1570        vld1.32         {d\i}, [r2,:64]
   1571        vst1.32         {d8},  [r2,:64], r12
   1572 .endr
   1573 .endif
   1574 .ifc \suffix,_half
   1575 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
   1576        vld1.32         {d\i}, [r2,:64]
   1577        vst1.32         {d8},  [r2,:64], r12
   1578 .endr
   1579 .endif
   1580 
   1581        bl              idct16\suffix
   1582 
   1583        @ Do eight 2x2 transposes. Originally, d16-d31 contain the
   1584        @ 16 rows. Afterwards, d16-d17, d18-d19 etc contain the eight
   1585        @ transposed 2x2 blocks.
   1586        transpose32_8x_2x2 d16, d17, d18, d19, d20, d21, d22, d23, d24, d25, d26, d27, d28, d29, d30, d31
   1587 
   1588        @ Store the registers a, b, c, d, e, f, g, h horizontally, followed
   1589        @ by the same registers h, g, f, e, d, c, b, a mirrored.
   1590 .macro store_rev a, b, c, d, e, f, g, h
   1591 .irp i, \a, \b, \c, \d, \e, \f, \g, \h
   1592        vst1.32         {d\i}, [r0,:64]!
   1593        vrev64.32       d\i, d\i
   1594 .endr
   1595 .irp i, \h, \g, \f, \e, \d, \c, \b, \a
   1596        vst1.32         {d\i}, [r0,:64]!
   1597 .endr
   1598 .endm
   1599        store_rev       16, 18, 20, 22, 24, 26, 28, 30
   1600        store_rev       17, 19, 21, 23, 25, 27, 29, 31
   1601        sub             r0,  r0,  #256
   1602 .purgem store_rev
   1603 
   1604        @ Move r2 back to the start of the input, and move
   1605        @ to the first odd row
   1606 .ifb \suffix
   1607        sub             r2,  r2,  r12, lsl #4
   1608 .endif
   1609 .ifc \suffix,_quarter
   1610        sub             r2,  r2,  r12, lsl #2
   1611 .endif
   1612 .ifc \suffix,_half
   1613        sub             r2,  r2,  r12, lsl #3
   1614 .endif
   1615        add             r2,  r2,  #128
   1616 
   1617        vmov.s32        d8,  #0
   1618        @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
   1619 .ifb \suffix
   1620 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
   1621        vld1.16         {d\i}, [r2,:64]
   1622        vst1.16         {d8},  [r2,:64], r12
   1623 .endr
   1624 .endif
   1625 .ifc \suffix,_quarter
   1626 .irp i, 16, 17, 18, 19
   1627        vld1.16         {d\i}, [r2,:64]
   1628        vst1.16         {d8},  [r2,:64], r12
   1629 .endr
   1630 .endif
   1631 .ifc \suffix,_half
   1632 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
   1633        vld1.16         {d\i}, [r2,:64]
   1634        vst1.16         {d8},  [r2,:64], r12
   1635 .endr
   1636 .endif
   1637 
   1638        bl              idct32_odd\suffix
   1639 
   1640        transpose32_8x_2x2 d31, d30, d29, d28, d27, d26, d25, d24, d23, d22, d21, d20, d19, d18, d17, d16
   1641 
   1642        @ Store the registers a, b, c, d, e, f, g, h horizontally,
   1643        @ adding into the output first, and then mirrored, subtracted
   1644        @ from the output.
   1645 .macro store_rev a, b, c, d, e, f, g, h
   1646 .irp i, \a, \b, \c, \d, \e, \f, \g, \h
   1647        vld1.32         {d8},  [r0,:64]
   1648        vadd.s32        d8, d8, d\i
   1649        vst1.32         {d8},  [r0,:64]!
   1650        vrev64.32       d\i, d\i
   1651 .endr
   1652 .irp i, \h, \g, \f, \e, \d, \c, \b, \a
   1653        vld1.32         {d8},  [r0,:64]
   1654        vsub.s32        d8, d8, d\i
   1655        vst1.32         {d8},  [r0,:64]!
   1656 .endr
   1657 .endm
   1658 
   1659        store_rev       31, 29, 27, 25, 23, 21, 19, 17
   1660        store_rev       30, 28, 26, 24, 22, 20, 18, 16
   1661 .purgem store_rev
   1662        pop             {pc}
   1663 endfunc
   1664 .ltorg
   1665 
   1666 @ This is mostly the same as 2x32_pass1, but without the transpose,
   1667 @ and use the source as temp buffer between the two idct passes, and
   1668 @ add into the destination.
   1669 @ r0 = dst
   1670 @ r1 = dst stride
   1671 @ r2 = src (temp buffer)
   1672 function idct32_1d_2x32_pass2\suffix\()_neon
   1673        push            {lr}
   1674 
   1675        mov             r12, #256
   1676        @ d16 = IN(0), d17 = IN(2) ... d31 = IN(30)
   1677 .ifb \suffix
   1678 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
   1679        vld1.32         {d\i}, [r2,:64], r12
   1680 .endr
   1681        sub             r2,  r2,  r12, lsl #4
   1682 .endif
   1683 .ifc \suffix,_quarter
   1684 .irp i, 16, 17, 18, 19
   1685        vld1.32         {d\i}, [r2,:64], r12
   1686 .endr
   1687        sub             r2,  r2,  r12, lsl #2
   1688 .endif
   1689 .ifc \suffix,_half
   1690 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
   1691        vld1.32         {d\i}, [r2,:64], r12
   1692 .endr
   1693        sub             r2,  r2,  r12, lsl #3
   1694 .endif
   1695 
   1696        bl              idct16\suffix
   1697 
   1698 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
   1699        vst1.32         {d\i}, [r2,:64], r12
   1700 .endr
   1701 
   1702        sub             r2,  r2,  r12, lsl #4
   1703        add             r2,  r2,  #128
   1704 
   1705        @ d16 = IN(1), d17 = IN(3) ... d31 = IN(31)
   1706 .ifb \suffix
   1707 .irp i, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
   1708        vld1.32         {d\i}, [r2,:64], r12
   1709 .endr
   1710        sub             r2,  r2,  r12, lsl #4
   1711 .endif
   1712 .ifc \suffix,_quarter
   1713 .irp i, 16, 17, 18, 19
   1714        vld1.32         {d\i}, [r2,:64], r12
   1715 .endr
   1716        sub             r2,  r2,  r12, lsl #2
   1717 .endif
   1718 .ifc \suffix,_half
   1719 .irp i, 16, 17, 18, 19, 20, 21, 22, 23
   1720        vld1.32         {d\i}, [r2,:64], r12
   1721 .endr
   1722        sub             r2,  r2,  r12, lsl #3
   1723 .endif
   1724        sub             r2,  r2,  #128
   1725 
   1726        bl              idct32_odd\suffix
   1727 
   1728        @ Narrow the ict16 coefficients in q0-q3 into q0-q1, to
   1729        @ allow clobbering q2-q3 below.
   1730        vmovn.s32       d0,  q0
   1731        vmovn.s32       d1,  q1
   1732        vmovn.s32       d2,  q2
   1733        vmovn.s32       d3,  q3
   1734 
   1735        mov             r12, #256
   1736        vdup.s16        q4,  r9
   1737 .macro load_acc_store a, b, c, d, neg=0
   1738        vld1.32         {d4},  [r2,:64], r12
   1739        vld1.32         {d5},  [r2,:64], r12
   1740 .if \neg == 0
   1741        vadd.s32        d4,  d4,  d\a
   1742        vld1.32         {d6},  [r2,:64], r12
   1743        vadd.s32        d5,  d5,  d\b
   1744        vld1.32         {d7},  [r2,:64], r12
   1745        vadd.s32        d6,  d6,  d\c
   1746        vadd.s32        d7,  d7,  d\d
   1747 .else
   1748        vsub.s32        d4,  d4,  d\a
   1749        vld1.32         {d6},  [r2,:64], r12
   1750        vsub.s32        d5,  d5,  d\b
   1751        vld1.32         {d7},  [r2,:64], r12
   1752        vsub.s32        d6,  d6,  d\c
   1753        vsub.s32        d7,  d7,  d\d
   1754 .endif
   1755        vld1.32         {d10[]},  [r0,:32], r1
   1756        vld1.32         {d10[1]}, [r0,:32], r1
   1757        vrshr.s32       q2,  q2,  #6
   1758        vld1.32         {d11[]},  [r0,:32], r1
   1759        vrshr.s32       q3,  q3,  #6
   1760        vld1.32         {d11[1]}, [r0,:32], r1
   1761        sub             r0,  r0,  r1, lsl #2
   1762        vaddw.u16       q2,  q2,  d10
   1763        vaddw.u16       q3,  q3,  d11
   1764        vqmovun.s32     d4,  q2
   1765        vqmovun.s32     d5,  q3
   1766        vmin.u16        q2,  q2,  q4
   1767        vst1.32         {d4[0]},  [r0,:32], r1
   1768        vst1.32         {d4[1]},  [r0,:32], r1
   1769        vst1.32         {d5[0]},  [r0,:32], r1
   1770        vst1.32         {d5[1]},  [r0,:32], r1
   1771 .endm
   1772        load_acc_store  31, 30, 29, 28
   1773        load_acc_store  27, 26, 25, 24
   1774        load_acc_store  23, 22, 21, 20
   1775        load_acc_store  19, 18, 17, 16
   1776        sub             r2,  r2,  r12
   1777        neg             r12, r12
   1778        load_acc_store  16, 17, 18, 19, 1
   1779        load_acc_store  20, 21, 22, 23, 1
   1780        load_acc_store  24, 25, 26, 27, 1
   1781        load_acc_store  28, 29, 30, 31, 1
   1782 .purgem load_acc_store
   1783        @ Lengthen the idct16 coeffs back into 32 bit form
   1784        vmovl.s16       q2,  d2
   1785        vmovl.s16       q3,  d3
   1786        vmovl.s16       q1,  d1
   1787        vmovl.s16       q0,  d0
   1788        pop             {pc}
   1789 endfunc
   1790 .endm
   1791 
   1792 idct32_funcs
   1793 idct32_funcs _quarter
   1794 idct32_funcs _half
   1795 
   1796 const min_eob_idct_idct_32, align=4
   1797        .short  0, 3, 9, 21, 34, 51, 70, 98, 135, 176, 240, 258, 336, 357, 448, 472
   1798 endconst
   1799 
   1800 function vp9_idct_idct_32x32_add_16_neon
   1801        cmp             r3,  #1
   1802        beq             idct32x32_dc_add_neon
   1803        vpush           {q4-q7}
   1804        movrel          r8,  min_eob_idct_idct_32 + 2
   1805 
   1806        @ Align the stack, allocate a temp buffer
   1807 T       mov             r7,  sp
   1808 T       and             r7,  r7,  #15
   1809 A       and             r7,  sp,  #15
   1810        add             r7,  r7,  #4096
   1811        sub             sp,  sp,  r7
   1812 
   1813        mov             r4,  r0
   1814        mov             r5,  r1
   1815        mov             r6,  r2
   1816 
   1817        movrel          r12, idct_coeffs
   1818        vld1.16         {q0-q1}, [r12,:128]!
   1819        vld1.16         {q6-q7}, [r12,:128]
   1820        vmovl.s16       q2,  d2
   1821        vmovl.s16       q3,  d3
   1822        vmovl.s16       q1,  d1
   1823        vmovl.s16       q0,  d0
   1824 
   1825        cmp             r3,  #34
   1826        ble             idct32x32_quarter_add_16_neon
   1827        cmp             r3,  #135
   1828        ble             idct32x32_half_add_16_neon
   1829 
   1830 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
   1831        add             r0,  sp,  #(\i*128)
   1832 .if \i > 0
   1833        ldrh_post       r1,  r8,  #2
   1834        cmp             r3,  r1
   1835        it              le
   1836        movle           r1,  #(32 - \i)/2
   1837        ble             1f
   1838 .endif
   1839        add             r2,  r6,  #(\i*4)
   1840        bl              idct32_1d_2x32_pass1_neon
   1841 .endr
   1842        b               3f
   1843 
   1844 1:
   1845        @ Write zeros to the temp buffer for pass 2
   1846        vmov.i16        q14, #0
   1847        vmov.i16        q15, #0
   1848 2:
   1849        subs            r1,  r1,  #1
   1850 .rept 2
   1851        @ Fill one line with zeros
   1852        vst1.16         {q14-q15}, [r0,:128]!
   1853        vst1.16         {q14-q15}, [r0,:128]!
   1854        vst1.16         {q14-q15}, [r0,:128]!
   1855        vst1.16         {q14-q15}, [r0,:128]!
   1856 .endr
   1857        bne             2b
   1858 3:
   1859 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
   1860        add             r0,  r4,  #(\i*2)
   1861        mov             r1,  r5
   1862        add             r2,  sp,  #(\i*4)
   1863        bl              idct32_1d_2x32_pass2_neon
   1864 .endr
   1865 
   1866        add             sp,  sp,  r7
   1867        vpop            {q4-q7}
   1868        pop             {r4-r9,pc}
   1869 endfunc
   1870 
   1871 function ff_vp9_idct_idct_32x32_add_10_neon, export=1
   1872        push            {r4-r9,lr}
   1873        movw            r9,  #0x03ff
   1874        b               vp9_idct_idct_32x32_add_16_neon
   1875 endfunc
   1876 
   1877 function ff_vp9_idct_idct_32x32_add_12_neon, export=1
   1878        push            {r4-r9,lr}
   1879        movw            r9,  #0x0fff
   1880        b               vp9_idct_idct_32x32_add_16_neon
   1881 endfunc
   1882 
   1883 .macro idct32_partial size, rows
   1884 function idct32x32_\size\()_add_16_neon
   1885 .irp i, 0, 2, 4, 6
   1886        add             r0,  sp,  #(\i*128)
   1887 .ifc \size,quarter
   1888 .if \i > 0
   1889        ldrh_post       r1,  r8,  #2
   1890        cmp             r3,  r1
   1891        it              le
   1892        movle           r1,  #(\rows - \i)/2
   1893        ble             1f
   1894 .endif
   1895 .endif
   1896        add             r2,  r6,  #(\i*4)
   1897        bl              idct32_1d_2x32_pass1_\size\()_neon
   1898 .endr
   1899 .ifc \size,half
   1900        add             r8,  r8,  #8
   1901 .irp i, 8, 10, 12, 14
   1902        add             r0,  sp,  #(\i*128)
   1903 .if \i > 8
   1904        ldrh_post       r1,  r8,  #2
   1905        cmp             r3,  r1
   1906        it              le
   1907        movle           r1,  #(\rows - \i)/2
   1908        ble             1f
   1909 .endif
   1910        add             r2,  r6,  #(\i*4)
   1911        bl              idct32_1d_2x32_pass1_\size\()_neon
   1912 .endr
   1913 .endif
   1914        b               3f
   1915 
   1916 1:
   1917        @ Write zeros to the temp buffer for pass 2
   1918        vmov.i16        q14, #0
   1919        vmov.i16        q15, #0
   1920 2:
   1921        subs            r1,  r1,  #1
   1922 .rept 2
   1923        @ Fill one line with zeros
   1924        vst1.16         {q14-q15}, [r0,:128]!
   1925        vst1.16         {q14-q15}, [r0,:128]!
   1926        vst1.16         {q14-q15}, [r0,:128]!
   1927        vst1.16         {q14-q15}, [r0,:128]!
   1928 .endr
   1929        bne             2b
   1930 3:
   1931 .irp i, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
   1932        add             r0,  r4,  #(\i*2)
   1933        mov             r1,  r5
   1934        add             r2,  sp,  #(\i*4)
   1935        bl              idct32_1d_2x32_pass2_\size\()_neon
   1936 .endr
   1937 
   1938        add             sp,  sp,  r7
   1939        vpop            {q4-q7}
   1940        pop             {r4-r9,pc}
   1941 endfunc
   1942 .endm
   1943 
   1944 idct32_partial quarter, 8
   1945 idct32_partial half, 16