tor-browser

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

ipred16.S (130503B)


      1 /*
      2 * Copyright © 2018, VideoLAN and dav1d authors
      3 * Copyright © 2019, B Krishnan Iyer
      4 * Copyright © 2020, Martin Storsjo
      5 * All rights reserved.
      6 *
      7 * Redistribution and use in source and binary forms, with or without
      8 * modification, are permitted provided that the following conditions are met:
      9 *
     10 * 1. Redistributions of source code must retain the above copyright notice, this
     11 *    list of conditions and the following disclaimer.
     12 *
     13 * 2. Redistributions in binary form must reproduce the above copyright notice,
     14 *    this list of conditions and the following disclaimer in the documentation
     15 *    and/or other materials provided with the distribution.
     16 *
     17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
     18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     20 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
     21 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     26 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28 
     29 #include "src/arm/asm.S"
     30 #include "util.S"
     31 
     32 // void ipred_dc_128_16bpc_neon(pixel *dst, const ptrdiff_t stride,
     33 //                              const pixel *const topleft,
     34 //                              const int width, const int height, const int a,
     35 //                              const int max_width, const int max_height,
     36 //                              const int bitdepth_max);
     37 function ipred_dc_128_16bpc_neon, export=1
     38        push            {r4, lr}
     39        ldr             r4,  [sp, #8]
     40        ldr             r12, [sp, #24]
     41        clz             r3,  r3
     42        adr             r2,  L(ipred_dc_128_tbl)
     43        sub             r3,  r3,  #25
     44        vdup.16         q0,  r12
     45        ldr             r3,  [r2,  r3,  lsl #2]
     46        add             r12, r0,  r1
     47        vrshr.u16       q0,  q0,  #1
     48        add             r2,  r2,  r3
     49        lsl             r1,  r1,  #1
     50        bx              r2
     51 
     52        .align 2
     53 L(ipred_dc_128_tbl):
     54        .word 640f - L(ipred_dc_128_tbl) + CONFIG_THUMB
     55        .word 320f - L(ipred_dc_128_tbl) + CONFIG_THUMB
     56        .word 160f - L(ipred_dc_128_tbl) + CONFIG_THUMB
     57        .word 8f   - L(ipred_dc_128_tbl) + CONFIG_THUMB
     58        .word 4f   - L(ipred_dc_128_tbl) + CONFIG_THUMB
     59 4:
     60        vst1.16         {d0},  [r0,  :64], r1
     61        vst1.16         {d0},  [r12, :64], r1
     62        subs            r4,  r4,  #4
     63        vst1.16         {d0},  [r0,  :64], r1
     64        vst1.16         {d0},  [r12, :64], r1
     65        bgt             4b
     66        pop             {r4, pc}
     67 8:
     68        vst1.16         {d0,  d1}, [r0,  :128], r1
     69        vst1.16         {d0,  d1}, [r12, :128], r1
     70        subs            r4,  r4,  #4
     71        vst1.16         {d0,  d1}, [r0,  :128], r1
     72        vst1.16         {d0,  d1}, [r12, :128], r1
     73        bgt             8b
     74        pop             {r4, pc}
     75 160:
     76        vmov            q1,  q0
     77 16:
     78        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
     79        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
     80        subs            r4,  r4,  #4
     81        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
     82        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
     83        bgt             16b
     84        pop             {r4, pc}
     85 320:
     86        vmov            q1,  q0
     87        sub             r1,  r1,  #32
     88 32:
     89        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
     90        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
     91        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
     92        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
     93        subs            r4,  r4,  #4
     94        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
     95        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
     96        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
     97        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
     98        bgt             32b
     99        pop             {r4, pc}
    100 640:
    101        vmov            q1,  q0
    102        sub             r1,  r1,  #96
    103 64:
    104        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    105        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    106        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    107        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    108        subs            r4,  r4,  #2
    109        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    110        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    111        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    112        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    113        bgt             64b
    114        pop             {r4, pc}
    115 endfunc
    116 
    117 // void ipred_v_16bpc_neon(pixel *dst, const ptrdiff_t stride,
    118 //                         const pixel *const topleft,
    119 //                         const int width, const int height, const int a,
    120 //                         const int max_width, const int max_height);
    121 function ipred_v_16bpc_neon, export=1
    122        push            {r4, lr}
    123        ldr             lr,  [sp, #8]
    124        clz             r3,  r3
    125        adr             r4,  L(ipred_v_tbl)
    126        sub             r3,  r3,  #25
    127        ldr             r3,  [r4,  r3,  lsl #2]
    128        add             r2,  r2,  #2
    129        add             r4,  r4,  r3
    130        add             r12, r0,  r1
    131        lsl             r1,  r1,  #1
    132        bx              r4
    133 
    134        .align 2
    135 L(ipred_v_tbl):
    136        .word 640f - L(ipred_v_tbl) + CONFIG_THUMB
    137        .word 320f - L(ipred_v_tbl) + CONFIG_THUMB
    138        .word 160f - L(ipred_v_tbl) + CONFIG_THUMB
    139        .word 80f  - L(ipred_v_tbl) + CONFIG_THUMB
    140        .word 40f  - L(ipred_v_tbl) + CONFIG_THUMB
    141 
    142 40:
    143        vld1.16         {d0}, [r2]
    144 4:
    145        vst1.16         {d0},  [r0,  :64], r1
    146        vst1.16         {d0},  [r12, :64], r1
    147        subs            lr,  lr,  #4
    148        vst1.16         {d0},  [r0,  :64], r1
    149        vst1.16         {d0},  [r12, :64], r1
    150        bgt             4b
    151        pop             {r4, pc}
    152 80:
    153        vld1.16         {q0},  [r2]
    154 8:
    155        vst1.16         {d0,  d1},  [r0,  :128], r1
    156        vst1.16         {d0,  d1},  [r12, :128], r1
    157        subs            lr,  lr,  #4
    158        vst1.16         {d0,  d1},  [r0,  :128], r1
    159        vst1.16         {d0,  d1},  [r12, :128], r1
    160        bgt             8b
    161        pop             {r4, pc}
    162 160:
    163        vld1.16         {q0,  q1},  [r2]
    164 16:
    165        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    166        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    167        subs            lr,  lr,  #4
    168        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    169        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    170        bgt             16b
    171        pop             {r4, pc}
    172 320:
    173        vld1.16         {q0,  q1},  [r2]!
    174        sub             r1,  r1,  #32
    175        vld1.16         {q2,  q3},  [r2]
    176 32:
    177        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    178        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    179        vst1.16         {d4,  d5,  d6,  d7},  [r0,  :128], r1
    180        vst1.16         {d4,  d5,  d6,  d7},  [r12, :128], r1
    181        subs            lr,  lr,  #4
    182        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    183        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    184        vst1.16         {d4,  d5,  d6,  d7},  [r0,  :128], r1
    185        vst1.16         {d4,  d5,  d6,  d7},  [r12, :128], r1
    186        bgt             32b
    187        pop             {r4, pc}
    188 640:
    189        vld1.16         {q0,  q1},  [r2]!
    190        sub             r1,  r1,  #96
    191        vld1.16         {q2,  q3},  [r2]!
    192        vld1.16         {q8,  q9},  [r2]!
    193        vld1.16         {q10, q11}, [r2]!
    194 64:
    195        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    196        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    197        vst1.16         {d4,  d5,  d6,  d7},  [r0,  :128]!
    198        vst1.16         {d4,  d5,  d6,  d7},  [r12, :128]!
    199        subs            lr,  lr,  #2
    200        vst1.16         {d16, d17, d18, d19}, [r0,  :128]!
    201        vst1.16         {d16, d17, d18, d19}, [r12, :128]!
    202        vst1.16         {d20, d21, d22, d23}, [r0,  :128], r1
    203        vst1.16         {d20, d21, d22, d23}, [r12, :128], r1
    204        bgt             64b
    205        pop             {r4, pc}
    206 endfunc
    207 
    208 // void ipred_h_16bpc_neon(pixel *dst, const ptrdiff_t stride,
    209 //                         const pixel *const topleft,
    210 //                         const int width, const int height, const int a,
    211 //                         const int max_width, const int max_height);
    212 function ipred_h_16bpc_neon, export=1
    213        push            {r4-r5, lr}
    214        ldr             r4,  [sp, #12]
    215        clz             r3,  r3
    216        adr             r5,  L(ipred_h_tbl)
    217        sub             r3,  r3,  #25
    218        ldr             r3,  [r5,  r3,  lsl #2]
    219        sub             r2,  r2,  #2
    220        mov             lr,  #-2
    221        add             r5,  r5,  r3
    222        add             r12, r0,  r1
    223        lsl             r1,  r1,  #1
    224        bx              r5
    225 
    226        .align 2
    227 L(ipred_h_tbl):
    228        .word 640f - L(ipred_h_tbl) + CONFIG_THUMB
    229        .word 320f - L(ipred_h_tbl) + CONFIG_THUMB
    230        .word 160f - L(ipred_h_tbl) + CONFIG_THUMB
    231        .word 8f   - L(ipred_h_tbl) + CONFIG_THUMB
    232        .word 40f  - L(ipred_h_tbl) + CONFIG_THUMB
    233 40:
    234        sub             r2,  r2,  #6
    235        mov             lr,  #-8
    236 4:
    237        vld4.16         {d0[],  d1[],  d2[],  d3[]},  [r2],  lr
    238        vst1.16         {d3},  [r0,  :64], r1
    239        vst1.16         {d2},  [r12, :64], r1
    240        subs            r4,  r4,  #4
    241        vst1.16         {d1},  [r0,  :64], r1
    242        vst1.16         {d0},  [r12, :64], r1
    243        bgt             4b
    244        pop             {r4-r5, pc}
    245 8:
    246        vld1.16         {d0[],  d1[]},  [r2],  lr
    247        subs            r4,  r4,  #4
    248        vld1.16         {d2[],  d3[]},  [r2],  lr
    249        vst1.16         {q0},  [r0,    :128],  r1
    250        vld1.16         {d4[],  d5[]},  [r2],  lr
    251        vst1.16         {q1},  [r12,   :128],  r1
    252        vld1.16         {d6[],  d7[]},  [r2],  lr
    253        vst1.16         {q2},  [r0,    :128],  r1
    254        vst1.16         {q3},  [r12,   :128],  r1
    255        bgt             8b
    256        pop             {r4-r5, pc}
    257 160:
    258        sub             r1,  r1,  #16
    259 16:
    260        vld1.16         {d0[],  d1[]}, [r2],  lr
    261        subs            r4,  r4,  #4
    262        vld1.16         {d2[],  d3[]}, [r2],  lr
    263        vst1.16         {q0},  [r0,   :128]!
    264        vld1.16         {d4[],  d5[]}, [r2],  lr
    265        vst1.16         {q1},  [r12,  :128]!
    266        vld1.16         {d6[],  d7[]}, [r2],  lr
    267        vst1.16         {q0},  [r0,   :128],  r1
    268        vst1.16         {q1},  [r12,  :128],  r1
    269        vst1.16         {q2},  [r0,   :128]!
    270        vst1.16         {q3},  [r12,  :128]!
    271        vst1.16         {q2},  [r0,   :128],  r1
    272        vst1.16         {q3},  [r12,  :128],  r1
    273        bgt             16b
    274        pop             {r4-r5, pc}
    275 320:
    276        sub             r1,  r1,  #48
    277 32:
    278        vld1.16         {d0[],  d1[]},  [r2],  lr
    279        subs            r4,  r4,  #4
    280        vld1.16         {d2[],  d3[]},  [r2],  lr
    281        vst1.16         {q0},  [r0,    :128]!
    282        vld1.16         {d4[],  d5[]},  [r2],  lr
    283        vst1.16         {q1},  [r12,   :128]!
    284        vld1.16         {d6[],  d7[]},  [r2],  lr
    285        vst1.16         {q0},  [r0,    :128]!
    286        vst1.16         {q1},  [r12,   :128]!
    287        vst1.16         {q0},  [r0,    :128]!
    288        vst1.16         {q1},  [r12,   :128]!
    289        vst1.16         {q0},  [r0,    :128],  r1
    290        vst1.16         {q1},  [r12,   :128],  r1
    291        vst1.16         {q2},  [r0,    :128]!
    292        vst1.16         {q3},  [r12,   :128]!
    293        vst1.16         {q2},  [r0,    :128]!
    294        vst1.16         {q3},  [r12,   :128]!
    295        vst1.16         {q2},  [r0,    :128]!
    296        vst1.16         {q3},  [r12,   :128]!
    297        vst1.16         {q2},  [r0,    :128],  r1
    298        vst1.16         {q3},  [r12,   :128],  r1
    299        bgt             32b
    300        pop             {r4-r5, pc}
    301 640:
    302        sub             r1,  r1,  #96
    303 64:
    304        vld1.16         {d0[],  d1[]},  [r2],  lr
    305        subs            r4,  r4,  #2
    306        vld1.16         {d4[],  d5[]},  [r2],  lr
    307        vmov            q1,  q0
    308        vmov            q3,  q2
    309        vst1.16         {q0, q1}, [r0,  :128]!
    310        vst1.16         {q2, q3}, [r12, :128]!
    311        vst1.16         {q0, q1}, [r0,  :128]!
    312        vst1.16         {q2, q3}, [r12, :128]!
    313        vst1.16         {q0, q1}, [r0,  :128]!
    314        vst1.16         {q2, q3}, [r12, :128]!
    315        vst1.16         {q0, q1}, [r0,  :128],  r1
    316        vst1.16         {q2, q3}, [r12, :128],  r1
    317        bgt             64b
    318        pop             {r4-r5, pc}
    319 endfunc
    320 
    321 // void ipred_dc_top_16bpc_neon(pixel *dst, const ptrdiff_t stride,
    322 //                              const pixel *const topleft,
    323 //                              const int width, const int height, const int a,
    324 //                              const int max_width, const int max_height);
    325 function ipred_dc_top_16bpc_neon, export=1
    326        push            {r4-r5, lr}
    327        ldr             r4,  [sp, #12]
    328        clz             r3,  r3
    329        adr             r5,  L(ipred_dc_top_tbl)
    330        sub             r3,  r3,  #25
    331        ldr             r3,  [r5,  r3,  lsl #2]
    332        add             r2,  r2,  #2
    333        add             r5,  r5,  r3
    334        add             r12, r0,  r1
    335        lsl             r1,  r1,  #1
    336        bx              r5
    337 
    338        .align 2
    339 L(ipred_dc_top_tbl):
    340        .word 640f - L(ipred_dc_top_tbl) + CONFIG_THUMB
    341        .word 320f - L(ipred_dc_top_tbl) + CONFIG_THUMB
    342        .word 160f - L(ipred_dc_top_tbl) + CONFIG_THUMB
    343        .word 80f  - L(ipred_dc_top_tbl) + CONFIG_THUMB
    344        .word 40f  - L(ipred_dc_top_tbl) + CONFIG_THUMB
    345 
    346 40:
    347        vld1.16         {d0},  [r2]
    348        vpadd.i16       d0,  d0,  d0
    349        vpadd.i16       d0,  d0,  d0
    350        vrshr.u16       d0,  d0,  #2
    351        vdup.16         d0,  d0[0]
    352 4:
    353        vst1.16         {d0},  [r0,  :64], r1
    354        vst1.16         {d0},  [r12, :64], r1
    355        subs            r4,  r4,  #4
    356        vst1.16         {d0},  [r0,  :64], r1
    357        vst1.16         {d0},  [r12, :64], r1
    358        bgt             4b
    359        pop             {r4-r5, pc}
    360 80:
    361        vld1.16         {d0,  d1},  [r2]
    362        vadd.i16        d0,  d0,  d1
    363        vpadd.i16       d0,  d0,  d0
    364        vpadd.i16       d0,  d0,  d0
    365        vrshr.u16       d0,  d0,  #3
    366        vdup.16         q0,  d0[0]
    367 8:
    368        vst1.16         {d0,  d1},  [r0,  :128], r1
    369        vst1.16         {d0,  d1},  [r12, :128], r1
    370        subs            r4,  r4,  #4
    371        vst1.16         {d0,  d1},  [r0,  :128], r1
    372        vst1.16         {d0,  d1},  [r12, :128], r1
    373        bgt             8b
    374        pop             {r4-r5, pc}
    375 160:
    376        vld1.16         {d0,  d1,  d2,  d3},  [r2]
    377        vadd.i16        q0,  q0,  q1
    378        vadd.i16        d0,  d0,  d1
    379        vpadd.i16       d0,  d0,  d0
    380        vpadd.i16       d0,  d0,  d0
    381        vrshr.u16       d4,  d0,  #4
    382        vdup.16         q0,  d4[0]
    383        vdup.16         q1,  d4[0]
    384 16:
    385        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    386        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    387        subs            r4,  r4,  #4
    388        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    389        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    390        bgt             16b
    391        pop             {r4-r5, pc}
    392 320:
    393        vld1.16         {d0,  d1,  d2,  d3},  [r2]!
    394        vld1.16         {d4,  d5,  d6,  d7},  [r2]
    395        vadd.i16        q0,  q0,  q1
    396        vadd.i16        q2,  q2,  q3
    397        vadd.i16        q0,  q0,  q2
    398        vadd.i16        d0,  d0,  d1
    399        vpadd.i16       d0,  d0,  d0
    400        vpaddl.u16      d0,  d0
    401        vrshrn.i32      d18, q0,  #5
    402        vdup.16         q0,  d18[0]
    403        vdup.16         q1,  d18[0]
    404        sub             r1,  r1,  #32
    405 32:
    406        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    407        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    408        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    409        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    410        subs            r4,  r4,  #4
    411        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    412        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    413        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    414        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    415        bgt             32b
    416        pop             {r4-r5, pc}
    417 640:
    418        vld1.16         {d0,  d1,  d2,  d3},  [r2]!
    419        vld1.16         {d4,  d5,  d6,  d7},  [r2]!
    420        vadd.i16        q0,  q0,  q1
    421        vld1.16         {d16, d17, d18, d19}, [r2]!
    422        vadd.i16        q2,  q2,  q3
    423        vld1.16         {d20, d21, d22, d23}, [r2]
    424        vadd.i16        q8,  q8,  q9
    425        vadd.i16        q10, q10, q11
    426        vadd.i16        q0,  q0,  q2
    427        vadd.i16        q8,  q8,  q10
    428        vadd.i16        q0,  q0,  q8
    429        vadd.i16        d0,  d0,  d1
    430        vpaddl.u16      d0,  d0
    431        vpadd.i32       d0,  d0,  d0
    432        vrshrn.i32      d18, q0,  #6
    433        vdup.16         q0,  d18[0]
    434        vdup.16         q1,  d18[0]
    435        sub             r1,  r1,  #96
    436 64:
    437        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    438        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    439        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    440        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    441        subs            r4,  r4,  #2
    442        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    443        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    444        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    445        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    446        bgt             64b
    447        pop             {r4-r5, pc}
    448 endfunc
    449 
    450 // void ipred_dc_left_16bpc_neon(pixel *dst, const ptrdiff_t stride,
    451 //                               const pixel *const topleft,
    452 //                               const int width, const int height, const int a,
    453 //                               const int max_width, const int max_height);
    454 function ipred_dc_left_16bpc_neon, export=1
    455        push            {r4-r5, lr}
    456        ldr             r4,  [sp, #12]
    457        sub             r2,  r2,  r4,  lsl #1
    458        clz             r3,  r3
    459        clz             lr,  r4
    460        sub             lr,  lr,  #25
    461        adr             r5,  L(ipred_dc_left_tbl)
    462        sub             r3,  r3,  #20
    463        ldr             r3,  [r5,  r3,  lsl #2]
    464        ldr             lr,  [r5,  lr,  lsl #2]
    465        add             r3,  r5,  r3
    466        add             r5,  r5,  lr
    467        add             r12, r0,  r1
    468        lsl             r1,  r1,  #1
    469        bx              r5
    470 
    471        .align 2
    472 L(ipred_dc_left_tbl):
    473        .word L(ipred_dc_left_h64) - L(ipred_dc_left_tbl) + CONFIG_THUMB
    474        .word L(ipred_dc_left_h32) - L(ipred_dc_left_tbl) + CONFIG_THUMB
    475        .word L(ipred_dc_left_h16) - L(ipred_dc_left_tbl) + CONFIG_THUMB
    476        .word L(ipred_dc_left_h8)  - L(ipred_dc_left_tbl) + CONFIG_THUMB
    477        .word L(ipred_dc_left_h4)  - L(ipred_dc_left_tbl) + CONFIG_THUMB
    478        .word L(ipred_dc_left_w64) - L(ipred_dc_left_tbl) + CONFIG_THUMB
    479        .word L(ipred_dc_left_w32) - L(ipred_dc_left_tbl) + CONFIG_THUMB
    480        .word L(ipred_dc_left_w16) - L(ipred_dc_left_tbl) + CONFIG_THUMB
    481        .word L(ipred_dc_left_w8)  - L(ipred_dc_left_tbl) + CONFIG_THUMB
    482        .word L(ipred_dc_left_w4)  - L(ipred_dc_left_tbl) + CONFIG_THUMB
    483 
    484 L(ipred_dc_left_h4):
    485        vld1.16         {d0},  [r2, :64]
    486        vpadd.i16       d0,  d0,  d0
    487        vpadd.i16       d0,  d0,  d0
    488        vrshr.u16       d0,  d0,  #2
    489        vdup.16         q0,  d0[0]
    490        bx              r3
    491 L(ipred_dc_left_w4):
    492        vst1.16         {d0},  [r0,  :64], r1
    493        vst1.16         {d0},  [r12, :64], r1
    494        subs            r4,  r4,  #4
    495        vst1.16         {d0},  [r0,  :64], r1
    496        vst1.16         {d0},  [r12, :64], r1
    497        bgt             L(ipred_dc_left_w4)
    498        pop             {r4-r5, pc}
    499 L(ipred_dc_left_h8):
    500        vld1.16         {d0,  d1},  [r2, :128]
    501        vadd.i16        d0,  d0,  d1
    502        vpadd.i16       d0,  d0,  d0
    503        vpadd.i16       d0,  d0,  d0
    504        vrshr.u16       d0,  d0,  #3
    505        vdup.16         q0,  d0[0]
    506        bx              r3
    507 L(ipred_dc_left_w8):
    508        vst1.16         {d0,  d1},  [r0,  :128], r1
    509        vst1.16         {d0,  d1},  [r12, :128], r1
    510        subs            r4,  r4,  #4
    511        vst1.16         {d0,  d1},  [r0,  :128], r1
    512        vst1.16         {d0,  d1},  [r12, :128], r1
    513        bgt             L(ipred_dc_left_w8)
    514        pop             {r4-r5, pc}
    515 L(ipred_dc_left_h16):
    516        vld1.16         {d0,  d1,  d2,  d3},  [r2, :128]
    517        vadd.i16        q0,  q0,  q1
    518        vadd.i16        d0,  d0,  d1
    519        vpadd.i16       d0,  d0,  d0
    520        vpadd.i16       d0,  d0,  d0
    521        vrshr.u16       d0,  d0,  #4
    522        vdup.16         q0,  d0[0]
    523        bx              r3
    524 L(ipred_dc_left_w16):
    525        vmov            q1,  q0
    526 1:
    527        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    528        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    529        subs            r4,  r4,  #4
    530        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    531        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    532        bgt             1b
    533        pop             {r4-r5, pc}
    534 L(ipred_dc_left_h32):
    535        vld1.16         {d0,  d1,  d2,  d3},  [r2, :128]!
    536        vld1.16         {d4,  d5,  d6,  d7},  [r2, :128]
    537        vadd.i16        q0,  q0,  q1
    538        vadd.i16        q2,  q2,  q3
    539        vadd.i16        q0,  q0,  q2
    540        vadd.i16        d0,  d0,  d1
    541        vpadd.i16       d0,  d0,  d0
    542        vpaddl.u16      d0,  d0
    543        vrshrn.i32      d0,  q0,  #5
    544        vdup.16         q0,  d0[0]
    545        bx              r3
    546 L(ipred_dc_left_w32):
    547        sub             r1,  r1,  #32
    548        vmov            q1,  q0
    549 1:
    550        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    551        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    552        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    553        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    554        subs            r4,  r4,  #4
    555        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    556        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    557        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    558        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    559        bgt             1b
    560        pop             {r4-r5, pc}
    561 L(ipred_dc_left_h64):
    562        vld1.16         {d0,  d1,  d2,  d3},  [r2, :128]!
    563        vld1.16         {d4,  d5,  d6,  d7},  [r2, :128]!
    564        vadd.i16        q0,  q0,  q1
    565        vld1.16         {d16, d17, d18, d19}, [r2, :128]!
    566        vadd.i16        q2,  q2,  q3
    567        vld1.16         {d20, d21, d22, d23}, [r2, :128]
    568        vadd.i16        q8,  q8,  q9
    569        vadd.i16        q10, q10, q11
    570        vadd.i16        q0,  q0,  q2
    571        vadd.i16        q8,  q8,  q10
    572        vadd.i16        q0,  q0,  q8
    573        vadd.i16        d0,  d0,  d1
    574        vpaddl.u16      d0,  d0
    575        vpadd.i32       d0,  d0,  d0
    576        vrshrn.i32      d0,  q0,  #6
    577        vdup.16         q0,  d0[0]
    578        bx              r3
    579 L(ipred_dc_left_w64):
    580        sub             r1,  r1,  #96
    581        vmov            q1,  q0
    582 1:
    583        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    584        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    585        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    586        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    587        subs            r4,  r4,  #2
    588        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    589        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    590        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    591        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    592        bgt             1b
    593        pop             {r4-r5, pc}
    594 endfunc
    595 
    596 // void ipred_dc_16bpc_neon(pixel *dst, const ptrdiff_t stride,
    597 //                          const pixel *const topleft,
    598 //                          const int width, const int height, const int a,
    599 //                          const int max_width, const int max_height);
    600 function ipred_dc_16bpc_neon, export=1
    601        push            {r4-r6, lr}
    602        ldr             r4,  [sp, #16]
    603        sub             r2,  r2,  r4,  lsl #1
    604        add             lr,  r3,  r4        // width + height
    605        clz             r3,  r3
    606        clz             r12, r4
    607        vdup.32         q15, lr             // width + height
    608        adr             r5,  L(ipred_dc_tbl)
    609        rbit            lr,  lr             // rbit(width + height)
    610        sub             r3,  r3,  #20       // 25 leading bits, minus table offset 5
    611        sub             r12, r12, #25
    612        clz             lr,  lr             // ctz(width + height)
    613        ldr             r3,  [r5,  r3,  lsl #2]
    614        ldr             r12, [r5,  r12, lsl #2]
    615        neg             lr,  lr             // -ctz(width + height)
    616        add             r3,  r5,  r3
    617        add             r5,  r5,  r12
    618        vshr.u32        q15, q15, #1        // (width + height) >> 1
    619        vdup.32         q14, lr             // -ctz(width + height)
    620        add             r12, r0,  r1
    621        lsl             r1,  r1,  #1
    622        bx              r5
    623 
    624        .align 2
    625 L(ipred_dc_tbl):
    626        .word L(ipred_dc_h64) - L(ipred_dc_tbl) + CONFIG_THUMB
    627        .word L(ipred_dc_h32) - L(ipred_dc_tbl) + CONFIG_THUMB
    628        .word L(ipred_dc_h16) - L(ipred_dc_tbl) + CONFIG_THUMB
    629        .word L(ipred_dc_h8)  - L(ipred_dc_tbl) + CONFIG_THUMB
    630        .word L(ipred_dc_h4)  - L(ipred_dc_tbl) + CONFIG_THUMB
    631        .word L(ipred_dc_w64) - L(ipred_dc_tbl) + CONFIG_THUMB
    632        .word L(ipred_dc_w32) - L(ipred_dc_tbl) + CONFIG_THUMB
    633        .word L(ipred_dc_w16) - L(ipred_dc_tbl) + CONFIG_THUMB
    634        .word L(ipred_dc_w8)  - L(ipred_dc_tbl) + CONFIG_THUMB
    635        .word L(ipred_dc_w4)  - L(ipred_dc_tbl) + CONFIG_THUMB
    636 
    637 L(ipred_dc_h4):
    638        vld1.16         {d0},  [r2, :64]!
    639        vpadd.i16       d0,  d0,  d0
    640        add             r2,  r2,  #2
    641        vpaddl.u16      d0,  d0
    642        bx              r3
    643 L(ipred_dc_w4):
    644        vld1.16         {d2},  [r2]
    645        vadd.i32        d0,  d0,  d30
    646        vpadd.i16       d2,  d2,  d2
    647        vpaddl.u16      d2,  d2
    648        cmp             r4,  #4
    649        vadd.i32        d0,  d0,  d2
    650        vshl.u32        d0,  d0,  d28
    651        beq             1f
    652        // h = 8/16
    653        cmp             r4,  #16
    654        movw            lr,  #0x6667
    655        movw            r5,  #0xAAAB
    656        it              ne
    657        movne           lr,  r5
    658        vdup.32         d24, lr
    659        vmul.i32        d0,  d0,  d24
    660        vshr.u32        d0,  d0,  #17
    661 1:
    662        vdup.16         d0,  d0[0]
    663 2:
    664        vst1.16         {d0},  [r0,  :64], r1
    665        vst1.16         {d0},  [r12, :64], r1
    666        subs            r4,  r4,  #4
    667        vst1.16         {d0},  [r0,  :64], r1
    668        vst1.16         {d0},  [r12, :64], r1
    669        bgt             2b
    670        pop             {r4-r6, pc}
    671 
    672 L(ipred_dc_h8):
    673        vld1.16         {d0,  d1},  [r2, :128]!
    674        vadd.i16        d0,  d0,  d1
    675        vpadd.i16       d0,  d0,  d0
    676        add             r2,  r2,  #2
    677        vpaddl.u16      d0,  d0
    678        bx              r3
    679 L(ipred_dc_w8):
    680        vld1.16         {d2,  d3},  [r2]
    681        vadd.i32        d0,  d0,  d30
    682        vadd.i16        d2,  d2,  d3
    683        vpadd.i16       d2,  d2,  d2
    684        vpaddl.u16      d2,  d2
    685        cmp             r4,  #8
    686        vadd.i32        d0,  d0,  d2
    687        vshl.u32        d0,  d0,  d28
    688        beq             1f
    689        // h = 4/16/32
    690        cmp             r4,  #32
    691        movw            lr,  #0x6667
    692        movw            r5,  #0xAAAB
    693        it              ne
    694        movne           lr,  r5
    695        vdup.32         d24, lr
    696        vmul.i32        d0,  d0,  d24
    697        vshr.u32        d0,  d0,  #17
    698 1:
    699        vdup.16         q0,  d0[0]
    700 2:
    701        vst1.16         {d0,  d1},  [r0,  :128], r1
    702        vst1.16         {d0,  d1},  [r12, :128], r1
    703        subs            r4,  r4,  #4
    704        vst1.16         {d0,  d1},  [r0,  :128], r1
    705        vst1.16         {d0,  d1},  [r12, :128], r1
    706        bgt             2b
    707        pop             {r4-r6, pc}
    708 
    709 L(ipred_dc_h16):
    710        vld1.16         {d0,  d1,  d2,  d3},  [r2, :128]!
    711        vadd.i16        q0,  q0,  q1
    712        vadd.i16        d0,  d0,  d1
    713        vpadd.i16       d0,  d0,  d0
    714        add             r2,  r2,  #2
    715        vpaddl.u16      d0,  d0
    716        bx              r3
    717 L(ipred_dc_w16):
    718        vld1.16         {d2,  d3,  d4,  d5},  [r2]
    719        vadd.i32        d0,  d0,  d30
    720        vadd.i16        q1,  q1,  q2
    721        vadd.i16        d2,  d2,  d3
    722        vpadd.i16       d2,  d2,  d1
    723        vpaddl.u16      d2,  d2
    724        cmp             r4,  #16
    725        vadd.i32        d0,  d0,  d2
    726        vshl.u32        d4,  d0,  d28
    727        beq             1f
    728        // h = 4/8/32/64
    729        tst             r4,  #(32+16+8)     // 16 added to make a consecutive bitmask
    730        movw            lr,  #0x6667
    731        movw            r5,  #0xAAAB
    732        it              ne
    733        movne           lr,  r5
    734        vdup.32         d24, lr
    735        vmul.i32        d4,  d4,  d24
    736        vshr.u32        d4,  d4,  #17
    737 1:
    738        vdup.16         q0,  d4[0]
    739        vdup.16         q1,  d4[0]
    740 2:
    741        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    742        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    743        subs            r4,  r4,  #4
    744        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    745        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    746        bgt             2b
    747        pop             {r4-r6, pc}
    748 
    749 L(ipred_dc_h32):
    750        vld1.16         {d0,  d1,  d2,  d3},  [r2, :128]!
    751        vld1.16         {d4,  d5,  d6,  d7},  [r2, :128]!
    752        vadd.i16        q0,  q0,  q1
    753        vadd.i16        q2,  q2,  q3
    754        vadd.i16        q0,  q0,  q2
    755        vadd.i16        d0,  d0,  d1
    756        vpadd.i16       d0,  d0,  d0
    757        add             r2,  r2,  #2
    758        vpaddl.u16      d0,  d0
    759        bx              r3
    760 L(ipred_dc_w32):
    761        vld1.16         {d2,  d3,  d4,  d5},  [r2]!
    762        vadd.i32        d0,  d0,  d30
    763        vld1.16         {d16, d17, d18, d19}, [r2]
    764        vadd.i16        q1,  q1,  q2
    765        vadd.i16        q8,  q8,  q9
    766        vadd.i16        q1,  q1,  q8
    767        vadd.i16        d2,  d2,  d3
    768        vpadd.i16       d2,  d2,  d2
    769        vpaddl.u16      d2,  d2
    770        cmp             r4,  #32
    771        vadd.i32        d0,  d0,  d2
    772        vshl.u32        d4,  d0,  d28
    773        beq             1f
    774        // h = 8/16/64
    775        cmp             r4,  #8
    776        movw            lr,  #0x6667
    777        movw            r5,  #0xAAAB
    778        it              ne
    779        movne           lr,  r5
    780        vdup.32         d24, lr
    781        vmul.i32        d4,  d4,  d24
    782        vshr.u32        d4,  d4,  #17
    783 1:
    784        sub             r1,  r1,  #32
    785        vdup.16         q0,  d4[0]
    786        vdup.16         q1,  d4[0]
    787 2:
    788        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    789        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    790        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    791        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    792        subs            r4,  r4,  #4
    793        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    794        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    795        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    796        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    797        bgt             2b
    798        pop             {r4-r6, pc}
    799 L(ipred_dc_h64):
    800        vld1.16         {d0,  d1,  d2,  d3},  [r2, :128]!
    801        vld1.16         {d4,  d5,  d6,  d7},  [r2, :128]!
    802        vadd.i16        q0,  q0,  q1
    803        vld1.16         {d16, d17, d18, d19}, [r2, :128]!
    804        vadd.i16        q2,  q2,  q3
    805        vld1.16         {d20, d21, d22, d23}, [r2, :128]!
    806        vadd.i16        q8,  q8,  q9
    807        vadd.i16        q10, q10, q11
    808        vadd.i16        q0,  q0,  q2
    809        vadd.i16        q8,  q8,  q10
    810        vadd.i16        q0,  q0,  q8
    811        vadd.i16        d0,  d0,  d1
    812        vpaddl.u16      d0,  d0
    813        add             r2,  r2,  #2
    814        vpadd.i32       d0,  d0,  d0
    815        bx              r3
    816 L(ipred_dc_w64):
    817        vld1.16         {d2,  d3,  d4,  d5},  [r2]!
    818        vadd.i32        d0,  d0,  d30
    819        vld1.16         {d16, d17, d18, d19}, [r2]!
    820        vadd.i16        q1,  q1,  q2
    821        vld1.16         {d20, d21, d22, d23}, [r2]!
    822        vadd.i16        q8,  q8,  q9
    823        vld1.16         {d24, d25, d26, d27}, [r2]!
    824        vadd.i16        q10, q10, q11
    825        vadd.i16        q12, q12, q13
    826        vadd.i16        q1,  q1,  q8
    827        vadd.i16        q10, q10, q12
    828        vadd.i16        q1,  q1,  q10
    829        vadd.i16        d2,  d2,  d3
    830        vpaddl.u16      d2,  d2
    831        vpadd.i32       d2,  d2,  d2
    832        cmp             r4,  #64
    833        vadd.i32        d0,  d0,  d2
    834        vshl.u32        d4,  d0,  d28
    835        beq             1f
    836        // h = 16/32
    837        cmp             r4,  #16
    838        movw            lr,  #0x6667
    839        movw            r5,  #0xAAAB
    840        it              ne
    841        movne           lr,  r5
    842        vdup.32         d24, lr
    843        vmul.i32        d4,  d4,  d24
    844        vshr.u32        d4,  d4,  #17
    845 1:
    846        sub             r1,  r1,  #96
    847        vdup.16         q0,  d4[0]
    848        vdup.16         q1,  d4[0]
    849 2:
    850        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    851        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    852        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    853        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    854        subs            r4,  r4,  #2
    855        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128]!
    856        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128]!
    857        vst1.16         {d0,  d1,  d2,  d3},  [r0,  :128], r1
    858        vst1.16         {d0,  d1,  d2,  d3},  [r12, :128], r1
    859        bgt             2b
    860        pop             {r4-r6, pc}
    861 endfunc
    862 
    863 // void ipred_paeth_16bpc_neon(pixel *dst, const ptrdiff_t stride,
    864 //                             const pixel *const topleft,
    865 //                             const int width, const int height, const int a,
    866 //                             const int max_width, const int max_height);
    867 function ipred_paeth_16bpc_neon, export=1
    868        push            {r4-r6, lr}
    869        vpush           {q4}
    870        ldr             r4,  [sp, #32]
    871        clz             lr,  r3
    872        adr             r12, L(ipred_paeth_tbl)
    873        sub             lr,  lr,  #25
    874        ldr             lr,  [r12, lr, lsl #2]
    875        vld1.16         {d4[], d5[]},  [r2]
    876        add             r6,  r2,  #2
    877        sub             r2,  r2,  #4
    878        add             r12, r12, lr
    879        mov             r5,  #-4
    880        add             lr,  r0,  r1
    881        lsl             r1,  r1,  #1
    882        bx              r12
    883 
    884        .align 2
    885 L(ipred_paeth_tbl):
    886        .word 640f - L(ipred_paeth_tbl) + CONFIG_THUMB
    887        .word 320f - L(ipred_paeth_tbl) + CONFIG_THUMB
    888        .word 160f - L(ipred_paeth_tbl) + CONFIG_THUMB
    889        .word 80f  - L(ipred_paeth_tbl) + CONFIG_THUMB
    890        .word 40f  - L(ipred_paeth_tbl) + CONFIG_THUMB
    891 
    892 40:
    893        sub             r2,  r2,  #4
    894        mov             r5,  #-8
    895        vld1.16         {d6},  [r6]
    896        vsub.i16        d16, d6,  d4  // top - topleft
    897        vmov            d7,  d6
    898        vmov            d17, d16
    899 4:
    900        vld4.16         {d0[], d1[], d2[], d3[]},  [r2, :64], r5
    901        vadd.i16        q9,  q8,  q0  // base
    902        vadd.i16        q10, q8,  q1
    903        vabd.s16        q11, q3,  q9  // tdiff
    904        vabd.s16        q12, q3,  q10
    905        vabd.s16        q13, q2,  q9  // tldiff
    906        vabd.s16        q14, q2,  q10
    907        vabd.s16        q9,  q0,  q9  // ldiff
    908        vabd.s16        q10, q1,  q10
    909        vmin.u16        q15, q11, q13 // min(tdiff, tldiff)
    910        vmin.u16        q4,  q12, q14
    911        vcge.u16        q11, q13, q11 // tldiff >= tdiff
    912        vcge.u16        q12, q14, q12
    913        vcge.u16        q9,  q15, q9  // min(tdiff, tldiff) >= ldiff
    914        vcge.u16        q10, q4,  q10
    915        vbsl            q12, q3,  q2  // tdiff <= tldiff ? top : topleft
    916        vbsl            q11, q3,  q2
    917        vbit            q12, q1,  q10 // ldiff <= min ? left : ...
    918        vbit            q11, q0,  q9
    919        vst1.16         {d25}, [r0, :64], r1
    920        vst1.16         {d24}, [lr, :64], r1
    921        subs            r4,  r4,  #4
    922        vst1.16         {d23}, [r0, :64], r1
    923        vst1.16         {d22}, [lr, :64], r1
    924        bgt             4b
    925        vpop            {q4}
    926        pop             {r4-r6, pc}
    927 80:
    928 160:
    929 320:
    930 640:
    931        vld1.16         {q3},  [r6]!
    932        mov             r12, r3
    933        sub             r1,  r1,  r3, lsl #1
    934 1:
    935        vld2.16         {d0[], d2[]},  [r2, :32], r5
    936        vmov            d1,  d0
    937        vmov            d3,  d2
    938 2:
    939        vsub.i16        q8,  q3,  q2  // top - topleft
    940        vadd.i16        q9,  q8,  q0  // base
    941        vadd.i16        q10, q8,  q1
    942        vabd.s16        q11, q3,  q9  // tdiff
    943        vabd.s16        q12, q3,  q10
    944        vabd.s16        q13, q2,  q9  // tldiff
    945        vabd.s16        q14, q2,  q10
    946        vabd.s16        q9,  q0,  q9  // ldiff
    947        vabd.s16        q10, q1,  q10
    948        vmin.u16        q15, q11, q13 // min(tdiff, tldiff)
    949        vmin.u16        q4,  q12, q14
    950        vcge.u16        q11, q13, q11 // tldiff >= tdiff
    951        vcge.u16        q12, q14, q12
    952        vcge.u16        q9,  q15, q9  // min(tdiff, tldiff) >= ldiff
    953        vcge.u16        q10, q4,  q10
    954        vbsl            q12, q3,  q2  // tdiff <= tldiff ? top : topleft
    955        vbsl            q11, q3,  q2
    956        vbit            q12, q1,  q10 // ldiff <= min ? left : ...
    957        vbit            q11, q0,  q9
    958        subs            r3,  r3,  #8
    959        vst1.16         {q12}, [r0, :128]!
    960        vst1.16         {q11}, [lr, :128]!
    961        ble             8f
    962        vld1.16         {q3},  [r6]!
    963        b               2b
    964 8:
    965        subs            r4,  r4,  #2
    966        ble             9f
    967        // End of horizontal loop, move pointers to next two rows
    968        sub             r6,  r6,  r12, lsl #1
    969        add             r0,  r0,  r1
    970        add             lr,  lr,  r1
    971        vld1.16         {q3},  [r6]!
    972        mov             r3,  r12
    973        b               1b
    974 9:
    975        vpop            {q4}
    976        pop             {r4-r6, pc}
    977 endfunc
    978 
    979 // void ipred_smooth_16bpc_neon(pixel *dst, const ptrdiff_t stride,
    980 //                              const pixel *const topleft,
    981 //                              const int width, const int height, const int a,
    982 //                              const int max_width, const int max_height);
    983 function ipred_smooth_16bpc_neon, export=1
    984        push            {r4-r10, lr}
    985        ldr             r4,  [sp, #32]
    986        movrel          r10, X(sm_weights)
    987        add             r12, r10, r4
    988        add             r10, r10, r3
    989        clz             r9,  r3
    990        adr             r5,  L(ipred_smooth_tbl)
    991        sub             lr,  r2,  r4, lsl #1
    992        sub             r9,  r9,  #25
    993        ldr             r9,  [r5, r9, lsl #2]
    994        vld1.16         {d4[], d5[]},  [lr] // bottom
    995        add             r8,  r2,  #2
    996        add             r5,  r5,  r9
    997        add             r6,  r0,  r1
    998        lsl             r1,  r1,  #1
    999        bx              r5
   1000 
   1001        .align 2
   1002 L(ipred_smooth_tbl):
   1003        .word 640f - L(ipred_smooth_tbl) + CONFIG_THUMB
   1004        .word 320f - L(ipred_smooth_tbl) + CONFIG_THUMB
   1005        .word 160f - L(ipred_smooth_tbl) + CONFIG_THUMB
   1006        .word 80f  - L(ipred_smooth_tbl) + CONFIG_THUMB
   1007        .word 40f  - L(ipred_smooth_tbl) + CONFIG_THUMB
   1008 
   1009 40:
   1010        vld1.16         {d16},   [r8]       // top
   1011        vld1.32         {d18[]}, [r10, :32] // weights_hor
   1012        sub             r2,  r2,  #8
   1013        mov             r7,  #-8
   1014        vdup.16         q3,  d16[3]   // right
   1015        vsub.i16        q8,  q8,  q2  // top-bottom
   1016        vmovl.u8        q9,  d18      // weights_hor
   1017        vadd.i16        d19, d4,  d6  // bottom+right
   1018 4:
   1019        vld4.16         {d0[],  d1[],  d2[],  d3[]},  [r2,  :64], r7 // left
   1020        vld4.8          {d20[], d21[], d22[], d23[]}, [r12, :32]!    // weights_ver
   1021        vshll.u16       q12, d19, #8  // (bottom+right)*256
   1022        vshll.u16       q13, d19, #8
   1023        vshll.u16       q14, d19, #8
   1024        vshll.u16       q15, d19, #8
   1025        vzip.32         d20, d21      // weights_ver
   1026        vzip.32         d22, d23
   1027        vsub.i16        q1,  q1,  q3  // left-right
   1028        vsub.i16        q0,  q0,  q3
   1029        vmovl.u8        q10, d20      // weights_ver
   1030        vmovl.u8        q11, d22
   1031        vmlal.s16       q12, d3,  d18 // += (left-right)*weights_hor
   1032        vmlal.s16       q13, d2,  d18 // (left flipped)
   1033        vmlal.s16       q14, d1,  d18
   1034        vmlal.s16       q15, d0,  d18
   1035        vmlal.s16       q12, d16, d20 // += (top-bottom)*weights_ver
   1036        vmlal.s16       q13, d16, d21
   1037        vmlal.s16       q14, d16, d22
   1038        vmlal.s16       q15, d16, d23
   1039        vrshrn.i32      d24, q12, #9
   1040        vrshrn.i32      d25, q13, #9
   1041        vrshrn.i32      d26, q14, #9
   1042        vrshrn.i32      d27, q15, #9
   1043        vst1.16         {d24}, [r0, :64], r1
   1044        vst1.16         {d25}, [r6, :64], r1
   1045        subs            r4,  r4,  #4
   1046        vst1.16         {d26}, [r0, :64], r1
   1047        vst1.16         {d27}, [r6, :64], r1
   1048        bgt             4b
   1049        pop             {r4-r10, pc}
   1050 80:
   1051        vld1.16         {q8},  [r8]       // top
   1052        vld1.8          {d18}, [r10, :64] // weights_hor
   1053        sub             r2,  r2,  #4
   1054        mov             r7,  #-4
   1055        vdup.16         q3,  d17[3]   // right
   1056        vsub.i16        q8,  q8,  q2  // top-bottom
   1057        vmovl.u8        q9,  d18      // weights_hor
   1058        vadd.i16        d3,  d4,  d6  // bottom+right
   1059 8:
   1060        vld2.16         {d0[],  d1[]},  [r2,  :32], r7 // left
   1061        vld2.8          {d20[], d22[]}, [r12, :16]!    // weights_ver
   1062        vshll.u16       q12, d3,  #8  // (bottom+right)*256
   1063        vshll.u16       q13, d3,  #8
   1064        vshll.u16       q14, d3,  #8
   1065        vshll.u16       q15, d3,  #8
   1066        vsub.i16        q0,  q0,  q3  // left-right
   1067        vmovl.u8        q10, d20      // weights_ver
   1068        vmovl.u8        q11, d22
   1069        vmlal.s16       q12, d1,  d18 // += (left-right)*weights_hor
   1070        vmlal.s16       q13, d1,  d19 // (left flipped)
   1071        vmlal.s16       q14, d0,  d18
   1072        vmlal.s16       q15, d0,  d19
   1073        vmlal.s16       q12, d16, d20 // += (top-bottom)*weights_ver
   1074        vmlal.s16       q13, d17, d20
   1075        vmlal.s16       q14, d16, d22
   1076        vmlal.s16       q15, d17, d22
   1077        vrshrn.i32      d24, q12, #9
   1078        vrshrn.i32      d25, q13, #9
   1079        vrshrn.i32      d26, q14, #9
   1080        vrshrn.i32      d27, q15, #9
   1081        subs            r4,  r4,  #2
   1082        vst1.16         {q12}, [r0, :128], r1
   1083        vst1.16         {q13}, [r6, :128], r1
   1084        bgt             8b
   1085        pop             {r4-r10, pc}
   1086 160:
   1087 320:
   1088 640:
   1089        add             lr,  r2,  r3, lsl #1
   1090        sub             r2,  r2,  #4
   1091        mov             r7,  #-4
   1092        vld1.16         {d6[], d7[]}, [lr] // right
   1093        sub             r1,  r1,  r3, lsl #1
   1094        mov             r9,  r3
   1095        vadd.i16        d3,  d4,  d6  // bottom+right
   1096 
   1097 1:
   1098        vld2.16         {d0[],  d1[]},  [r2,  :32], r7 // left
   1099        vld2.8          {d20[], d22[]}, [r12, :16]!    // weights_ver
   1100        vsub.i16        q0,  q0,  q3  // left-right
   1101        vmovl.u8        q10, d20      // weights_ver
   1102        vmovl.u8        q11, d22
   1103 2:
   1104        vld1.8          {d18}, [r10, :64]! // weights_hor
   1105        vld1.16         {q8},  [r8]!       // top
   1106        vshll.u16       q12, d3,  #8  // (bottom+right)*256
   1107        vshll.u16       q13, d3,  #8
   1108        vmovl.u8        q9,  d18      // weights_hor
   1109        vshll.u16       q14, d3,  #8
   1110        vshll.u16       q15, d3,  #8
   1111        vsub.i16        q8,  q8,  q2  // top-bottom
   1112        vmlal.s16       q12, d1,  d18 // += (left-right)*weights_hor
   1113        vmlal.s16       q13, d1,  d19 // (left flipped)
   1114        vmlal.s16       q14, d0,  d18
   1115        vmlal.s16       q15, d0,  d19
   1116        vmlal.s16       q12, d16, d20 // += (top-bottom)*weights_ver
   1117        vmlal.s16       q13, d17, d20
   1118        vmlal.s16       q14, d16, d22
   1119        vmlal.s16       q15, d17, d22
   1120        vrshrn.i32      d24, q12, #9
   1121        vrshrn.i32      d25, q13, #9
   1122        vrshrn.i32      d26, q14, #9
   1123        vrshrn.i32      d27, q15, #9
   1124        subs            r3,  r3,  #8
   1125        vst1.16         {q12}, [r0, :128]!
   1126        vst1.16         {q13}, [r6, :128]!
   1127        bgt             2b
   1128        subs            r4,  r4,  #2
   1129        ble             9f
   1130        sub             r8,  r8,  r9, lsl #1
   1131        sub             r10, r10, r9
   1132        add             r0,  r0,  r1
   1133        add             r6,  r6,  r1
   1134        mov             r3,  r9
   1135        b               1b
   1136 9:
   1137        pop             {r4-r10, pc}
   1138 endfunc
   1139 
   1140 // void ipred_smooth_v_16bpc_neon(pixel *dst, const ptrdiff_t stride,
   1141 //                                const pixel *const topleft,
   1142 //                                const int width, const int height, const int a,
   1143 //                                const int max_width, const int max_height);
   1144 function ipred_smooth_v_16bpc_neon, export=1
   1145        push            {r4-r7, lr}
   1146        ldr             r4,  [sp, #20]
   1147        movrel          r7,  X(sm_weights)
   1148        add             r7,  r7,  r4
   1149        clz             lr,  r3
   1150        adr             r5,  L(ipred_smooth_v_tbl)
   1151        sub             r12, r2,  r4,  lsl #1
   1152        sub             lr,  lr,  #25
   1153        ldr             lr,  [r5, lr, lsl #2]
   1154        vld1.16         {d4[], d5[]},  [r12] // bottom
   1155        add             r2,  r2,  #2
   1156        add             r5,  r5,  lr
   1157        add             r6,  r0,  r1
   1158        lsl             r1,  r1,  #1
   1159        bx              r5
   1160 
   1161        .align 2
   1162 L(ipred_smooth_v_tbl):
   1163        .word 640f - L(ipred_smooth_v_tbl) + CONFIG_THUMB
   1164        .word 320f - L(ipred_smooth_v_tbl) + CONFIG_THUMB
   1165        .word 160f - L(ipred_smooth_v_tbl) + CONFIG_THUMB
   1166        .word 80f  - L(ipred_smooth_v_tbl) + CONFIG_THUMB
   1167        .word 40f  - L(ipred_smooth_v_tbl) + CONFIG_THUMB
   1168 
   1169 40:
   1170        vld1.16         {d6}, [r2]    // top
   1171        vsub.i16        d6,  d6,  d4  // top-bottom
   1172        vmov            d7,  d6
   1173 4:
   1174        vld4.8          {d16[], d17[], d18[], d19[]}, [r7, :32]! // weights_ver
   1175        vzip.32         d16, d17      // weights_ver
   1176        vzip.32         d18, d19
   1177        vshll.u8        q8,  d16, #7  // weights_ver << 7
   1178        vshll.u8        q9,  d18, #7
   1179        vqrdmulh.s16    q10, q3,  q8  // ((top-bottom)*weights_ver + 128) >> 8
   1180        vqrdmulh.s16    q11, q3,  q9
   1181        vadd.i16        q10, q10, q2
   1182        vadd.i16        q11, q11, q2
   1183        vst1.16         {d20}, [r0, :64], r1
   1184        vst1.16         {d21}, [r6, :64], r1
   1185        subs            r4,  r4,  #4
   1186        vst1.16         {d22}, [r0, :64], r1
   1187        vst1.16         {d23}, [r6, :64], r1
   1188        bgt             4b
   1189        pop             {r4-r7, pc}
   1190 80:
   1191        vld1.16         {q3}, [r2]    // top
   1192        vsub.i16        q3,  q3,  q2  // top-bottom
   1193 8:
   1194        vld4.8          {d16[], d18[], d20[], d22[]}, [r7, :32]! // weights_ver
   1195        vshll.u8        q8,  d16, #7  // weights_ver << 7
   1196        vshll.u8        q9,  d18, #7
   1197        vshll.u8        q10, d20, #7
   1198        vshll.u8        q11, d22, #7
   1199        vqrdmulh.s16    q8,  q3,  q8  // ((top-bottom)*weights_ver + 128) >> 8
   1200        vqrdmulh.s16    q9,  q3,  q9
   1201        vqrdmulh.s16    q10, q3,  q10
   1202        vqrdmulh.s16    q11, q3,  q11
   1203        vadd.i16        q8,  q8,  q2
   1204        vadd.i16        q9,  q9,  q2
   1205        vadd.i16        q10, q10, q2
   1206        vadd.i16        q11, q11, q2
   1207        vst1.16         {q8},  [r0, :128], r1
   1208        vst1.16         {q9},  [r6, :128], r1
   1209        subs            r4,  r4,  #4
   1210        vst1.16         {q10}, [r0, :128], r1
   1211        vst1.16         {q11}, [r6, :128], r1
   1212        bgt             8b
   1213        pop             {r4-r7, pc}
   1214 160:
   1215 320:
   1216 640:
   1217        vpush           {q4-q7}
   1218        // Set up pointers for four rows in parallel; r0, r6, r5, lr
   1219        add             r5,  r0,  r1
   1220        add             lr,  r6,  r1
   1221        lsl             r1,  r1,  #1
   1222        sub             r1,  r1,  r3, lsl #1
   1223        mov             r12, r3
   1224 
   1225 1:
   1226        vld4.8          {d8[], d10[], d12[], d14[]}, [r7, :32]! // weights_ver
   1227        vshll.u8        q4,  d8,  #7  // weights_ver << 7
   1228        vshll.u8        q5,  d10, #7
   1229        vshll.u8        q6,  d12, #7
   1230        vshll.u8        q7,  d14, #7
   1231 2:
   1232        vld1.16         {q0, q1}, [r2]!  // top
   1233        vsub.i16        q0,  q0,  q2  // top-bottom
   1234        vsub.i16        q1,  q1,  q2
   1235        vqrdmulh.s16    q8,  q0,  q4  // ((top-bottom)*weights_ver + 128) >> 8
   1236        vqrdmulh.s16    q9,  q1,  q4
   1237        vqrdmulh.s16    q10, q0,  q5
   1238        vqrdmulh.s16    q11, q1,  q5
   1239        vqrdmulh.s16    q12, q0,  q6
   1240        vqrdmulh.s16    q13, q1,  q6
   1241        vqrdmulh.s16    q14, q0,  q7
   1242        vqrdmulh.s16    q15, q1,  q7
   1243        vadd.i16        q8,  q8,  q2
   1244        vadd.i16        q9,  q9,  q2
   1245        vadd.i16        q10, q10, q2
   1246        vadd.i16        q11, q11, q2
   1247        vadd.i16        q12, q12, q2
   1248        vadd.i16        q13, q13, q2
   1249        vadd.i16        q14, q14, q2
   1250        vadd.i16        q15, q15, q2
   1251        subs            r3,  r3,  #16
   1252        vst1.16         {q8,  q9},  [r0, :128]!
   1253        vst1.16         {q10, q11}, [r6, :128]!
   1254        vst1.16         {q12, q13}, [r5, :128]!
   1255        vst1.16         {q14, q15}, [lr, :128]!
   1256        bgt             2b
   1257        subs            r4,  r4,  #4
   1258        ble             9f
   1259        sub             r2,  r2,  r12, lsl #1
   1260        add             r0,  r0,  r1
   1261        add             r6,  r6,  r1
   1262        add             r5,  r5,  r1
   1263        add             lr,  lr,  r1
   1264        mov             r3,  r12
   1265        b               1b
   1266 9:
   1267        vpop            {q4-q7}
   1268        pop             {r4-r7, pc}
   1269 endfunc
   1270 
   1271 // void ipred_smooth_h_16bpc_neon(pixel *dst, const ptrdiff_t stride,
   1272 //                                const pixel *const topleft,
   1273 //                                const int width, const int height, const int a,
   1274 //                                const int max_width, const int max_height);
   1275 function ipred_smooth_h_16bpc_neon, export=1
   1276        push            {r4-r8, lr}
   1277        ldr             r4,  [sp, #24]
   1278        movrel          r8,  X(sm_weights)
   1279        add             r8,  r8,  r3
   1280        clz             lr,  r3
   1281        adr             r5,  L(ipred_smooth_h_tbl)
   1282        add             r12, r2,  r3, lsl #1
   1283        sub             lr,  lr,  #25
   1284        ldr             lr,  [r5, lr, lsl #2]
   1285        vld1.16         {d4[], d5[]},  [r12] // right
   1286        add             r5,  r5,  lr
   1287        add             r6,  r0,  r1
   1288        lsl             r1,  r1,  #1
   1289        bx              r5
   1290 
   1291        .align 2
   1292 L(ipred_smooth_h_tbl):
   1293        .word 640f - L(ipred_smooth_h_tbl) + CONFIG_THUMB
   1294        .word 320f - L(ipred_smooth_h_tbl) + CONFIG_THUMB
   1295        .word 160f - L(ipred_smooth_h_tbl) + CONFIG_THUMB
   1296        .word 80f  - L(ipred_smooth_h_tbl) + CONFIG_THUMB
   1297        .word 40f  - L(ipred_smooth_h_tbl) + CONFIG_THUMB
   1298 
   1299 40:
   1300        vld1.32         {d6[]}, [r8, :32] // weights_hor
   1301        sub             r2,  r2,  #8
   1302        mov             r7,  #-8
   1303        vshll.u8        q3,  d6,  #7  // weights_hor << 7
   1304 4:
   1305        vld4.16         {d0[], d1[], d2[], d3[]},  [r2, :64], r7 // left
   1306        vsub.i16        q0,  q0,  q2  // left-right
   1307        vsub.i16        q1,  q1,  q2
   1308        subs            r4,  r4,  #4
   1309        vqrdmulh.s16    q8,  q1,  q3  // ((left-right)*weights_hor + 128) >> 8
   1310        vqrdmulh.s16    q9,  q0,  q3  // (left flipped)
   1311        vadd.i16        q8,  q8,  q2
   1312        vadd.i16        q9,  q9,  q2
   1313        vst1.16         {d17}, [r0, :64], r1
   1314        vst1.16         {d16}, [r6, :64], r1
   1315        vst1.16         {d19}, [r0, :64], r1
   1316        vst1.16         {d18}, [r6, :64], r1
   1317        bgt             4b
   1318        pop             {r4-r8, pc}
   1319 80:
   1320        vld1.8          {d6}, [r8, :64] // weights_hor
   1321        sub             r2,  r2,  #8
   1322        mov             r7,  #-8
   1323        vshll.u8        q3,  d6,  #7  // weights_hor << 7
   1324 8:
   1325        vld1.16         {d23},  [r2, :64], r7 // left
   1326        subs            r4,  r4,  #4
   1327        vsub.i16        d23, d23, d4  // left-right
   1328        vdup.16         q8,  d23[3]   // flip left
   1329        vdup.16         q9,  d23[2]
   1330        vdup.16         q10, d23[1]
   1331        vdup.16         q11, d23[0]
   1332        vqrdmulh.s16    q8,  q8,  q3  // ((left-right)*weights_hor + 128) >> 8
   1333        vqrdmulh.s16    q9,  q9,  q3
   1334        vqrdmulh.s16    q10, q10, q3
   1335        vqrdmulh.s16    q11, q11, q3
   1336        vadd.i16        q8,  q8,  q2
   1337        vadd.i16        q9,  q9,  q2
   1338        vadd.i16        q10, q10, q2
   1339        vadd.i16        q11, q11, q2
   1340        vst1.16         {q8},  [r0, :128], r1
   1341        vst1.16         {q9},  [r6, :128], r1
   1342        vst1.16         {q10}, [r0, :128], r1
   1343        vst1.16         {q11}, [r6, :128], r1
   1344        bgt             8b
   1345        pop             {r4-r8, pc}
   1346 160:
   1347 320:
   1348 640:
   1349        vpush           {q4-q7}
   1350        sub             r2,  r2,  #8
   1351        mov             r7,  #-8
   1352        // Set up pointers for four rows in parallel; r0, r6, r5, lr
   1353        add             r5,  r0,  r1
   1354        add             lr,  r6,  r1
   1355        lsl             r1,  r1,  #1
   1356        sub             r1,  r1,  r3, lsl #1
   1357        mov             r12, r3
   1358 
   1359 1:
   1360        vld1.16         {d15},  [r2, :64], r7 // left
   1361        vsub.i16        d15, d15, d4  // left-right
   1362        vdup.16         q4,  d15[3]   // flip left
   1363        vdup.16         q5,  d15[2]
   1364        vdup.16         q6,  d15[1]
   1365        vdup.16         q7,  d15[0]
   1366 2:
   1367        vld1.8          {q1}, [r8, :128]! // weights_hor
   1368        subs            r3,  r3,  #16
   1369        vshll.u8        q0,  d2,  #7  // weights_hor << 7
   1370        vshll.u8        q1,  d3,  #7
   1371        vqrdmulh.s16    q8,  q0,  q4  // ((left-right)*weights_hor + 128) >> 8
   1372        vqrdmulh.s16    q9,  q1,  q4
   1373        vqrdmulh.s16    q10, q0,  q5
   1374        vqrdmulh.s16    q11, q1,  q5
   1375        vqrdmulh.s16    q12, q0,  q6
   1376        vqrdmulh.s16    q13, q1,  q6
   1377        vqrdmulh.s16    q14, q0,  q7
   1378        vqrdmulh.s16    q15, q1,  q7
   1379        vadd.i16        q8,  q8,  q2
   1380        vadd.i16        q9,  q9,  q2
   1381        vadd.i16        q10, q10, q2
   1382        vadd.i16        q11, q11, q2
   1383        vadd.i16        q12, q12, q2
   1384        vadd.i16        q13, q13, q2
   1385        vadd.i16        q14, q14, q2
   1386        vadd.i16        q15, q15, q2
   1387        vst1.16         {q8,  q9},  [r0, :128]!
   1388        vst1.16         {q10, q11}, [r6, :128]!
   1389        vst1.16         {q12, q13}, [r5, :128]!
   1390        vst1.16         {q14, q15}, [lr, :128]!
   1391        bgt             2b
   1392        subs            r4,  r4,  #4
   1393        ble             9f
   1394        sub             r8,  r8,  r12
   1395        add             r0,  r0,  r1
   1396        add             r6,  r6,  r1
   1397        add             r5,  r5,  r1
   1398        add             lr,  lr,  r1
   1399        mov             r3,  r12
   1400        b               1b
   1401 9:
   1402        vpop            {q4-q7}
   1403        pop             {r4-r8, pc}
   1404 endfunc
   1405 
   1406 // void ipred_filter_16bpc_neon(pixel *dst, const ptrdiff_t stride,
   1407 //                              const pixel *const topleft,
   1408 //                              const int width, const int height, const int filt_idx,
   1409 //                              const int max_width, const int max_height,
   1410 //                              const int bitdepth_max);
   1411 .macro filter_fn bpc
   1412 function ipred_filter_\bpc\()bpc_neon, export=1
   1413        movw            r12, #511
   1414        ldrd            r4,  r5,   [sp, #88]
   1415        and             r5,  r5,  r12 // 511
   1416        movrel          r6,  X(filter_intra_taps)
   1417        lsl             r5,  r5,  #6
   1418        add             r6,  r6,  r5
   1419        vld1.8          {d20, d21, d22, d23}, [r6, :128]!
   1420        clz             lr,  r3
   1421        adr             r5,  L(ipred_filter\bpc\()_tbl)
   1422        vld1.8          {d27, d28, d29}, [r6, :64]
   1423        sub             lr,  lr,  #26
   1424        ldr             lr,  [r5, lr, lsl #2]
   1425        vmovl.s8        q8,  d20
   1426        vmovl.s8        q9,  d21
   1427        add             r5,  r5,  lr
   1428        vmovl.s8        q10, d22
   1429        vmovl.s8        q11, d23
   1430        add             r6,  r0,  r1
   1431        lsl             r1,  r1,  #1
   1432        vmovl.s8        q12, d27
   1433        vmovl.s8        q13, d28
   1434        vmovl.s8        q14, d29
   1435        mov             r7,  #-4
   1436        vdup.16         q15, r8
   1437        add             r8,  r2,  #2
   1438        sub             r2,  r2,  #4
   1439 .if \bpc == 10
   1440        vmov.i16        q7,  #0
   1441 .endif
   1442        bx              r5
   1443 
   1444        .align 2
   1445 L(ipred_filter\bpc\()_tbl):
   1446        .word 320f - L(ipred_filter\bpc\()_tbl) + CONFIG_THUMB
   1447        .word 160f - L(ipred_filter\bpc\()_tbl) + CONFIG_THUMB
   1448        .word 80f  - L(ipred_filter\bpc\()_tbl) + CONFIG_THUMB
   1449        .word 40f  - L(ipred_filter\bpc\()_tbl) + CONFIG_THUMB
   1450 
   1451 40:
   1452        vld1.16         {d0}, [r8]       // top (0-3)
   1453 4:
   1454        vld1.16         {d2}, [r2], r7   // left (0-1) + topleft (2)
   1455 .if \bpc == 10
   1456        vmul.i16        q2,  q9,  d0[0]  // p1(top[0]) * filter(1)
   1457        vmla.i16        q2,  q10, d0[1]  // p2(top[1]) * filter(2)
   1458        vmla.i16        q2,  q11, d0[2]  // p3(top[2]) * filter(3)
   1459        vmla.i16        q2,  q12, d0[3]  // p4(top[3]) * filter(4)
   1460        vmla.i16        q2,  q8,  d2[2]  // p0(topleft) * filter(0)
   1461        vmla.i16        q2,  q13, d2[1]  // p5(left[0]) * filter(5)
   1462        vmla.i16        q2,  q14, d2[0]  // p6(left[1]) * filter(6)
   1463        vrshr.s16       q2,  q2,  #4
   1464        vmax.s16        q2,  q2,  q7
   1465 .else
   1466        vmull.s16       q2,  d18, d0[0]  // p1(top[0]) * filter(1)
   1467        vmlal.s16       q2,  d20, d0[1]  // p2(top[1]) * filter(2)
   1468        vmlal.s16       q2,  d22, d0[2]  // p3(top[2]) * filter(3)
   1469        vmlal.s16       q2,  d24, d0[3]  // p4(top[3]) * filter(4)
   1470        vmlal.s16       q2,  d16, d2[2]  // p0(topleft) * filter(0)
   1471        vmlal.s16       q2,  d26, d2[1]  // p5(left[0]) * filter(5)
   1472        vmlal.s16       q2,  d28, d2[0]  // p6(left[1]) * filter(6)
   1473        vmull.s16       q3,  d19, d0[0]  // p1(top[0]) * filter(1)
   1474        vmlal.s16       q3,  d21, d0[1]  // p2(top[1]) * filter(2)
   1475        vmlal.s16       q3,  d23, d0[2]  // p3(top[2]) * filter(3)
   1476        vmlal.s16       q3,  d25, d0[3]  // p4(top[3]) * filter(4)
   1477        vmlal.s16       q3,  d17, d2[2]  // p0(topleft) * filter(0)
   1478        vmlal.s16       q3,  d27, d2[1]  // p5(left[0]) * filter(5)
   1479        vmlal.s16       q3,  d29, d2[0]  // p6(left[1]) * filter(6)
   1480        vqrshrun.s32    d4,  q2,  #4
   1481        vqrshrun.s32    d5,  q3,  #4
   1482 .endif
   1483        vmin.s16        q2,  q2,  q15
   1484        subs            r4,  r4,  #2
   1485        vst1.16         {d4}, [r0, :64], r1
   1486        vst1.16         {d5}, [r6, :64], r1
   1487        vmov            d0,  d5          // move top from [4-7] to [0-3]
   1488        bgt             4b
   1489        vpop            {q4-q7}
   1490        pop             {r4-r8, pc}
   1491 80:
   1492        vld1.16         {q0},  [r8]      // top (0-7)
   1493 8:
   1494        vld1.16         {d2}, [r2], r7   // left (0-1) + topleft (2)
   1495 .if \bpc == 10
   1496        vmul.i16        q2,  q9,  d0[0]  // p1(top[0]) * filter(1)
   1497        vmla.i16        q2,  q10, d0[1]  // p2(top[1]) * filter(2)
   1498        vmla.i16        q2,  q11, d0[2]  // p3(top[2]) * filter(3)
   1499        vmla.i16        q2,  q12, d0[3]  // p4(top[3]) * filter(4)
   1500        vmla.i16        q2,  q8,  d2[2]  // p0(topleft) * filter(0)
   1501        vmla.i16        q2,  q13, d2[1]  // p5(left[0]) * filter(5)
   1502        vmla.i16        q2,  q14, d2[0]  // p6(left[1]) * filter(6)
   1503        vmul.i16        q3,  q9,  d1[0]  // p1(top[0]) * filter(1)
   1504        vmla.i16        q3,  q10, d1[1]  // p2(top[1]) * filter(2)
   1505        vmla.i16        q3,  q11, d1[2]  // p3(top[2]) * filter(3)
   1506        vrshr.s16       q2,  q2,  #4
   1507        vmax.s16        q2,  q2,  q7
   1508        vmin.s16        q2,  q2,  q15
   1509        vmla.i16        q3,  q12, d1[3]  // p4(top[3]) * filter(4)
   1510        vmla.i16        q3,  q8,  d0[3]  // p0(topleft) * filter(0)
   1511        vmla.i16        q3,  q13, d4[3]  // p5(left[0]) * filter(5)
   1512        vmla.i16        q3,  q14, d5[3]  // p6(left[1]) * filter(6)
   1513        vrshr.s16       q3,  q3,  #4
   1514        vmax.s16        q3,  q3,  q7
   1515 .else
   1516        vmull.s16       q2,  d18, d0[0]  // p1(top[0]) * filter(1)
   1517        vmlal.s16       q2,  d20, d0[1]  // p2(top[1]) * filter(2)
   1518        vmlal.s16       q2,  d22, d0[2]  // p3(top[2]) * filter(3)
   1519        vmlal.s16       q2,  d24, d0[3]  // p4(top[3]) * filter(4)
   1520        vmlal.s16       q2,  d16, d2[2]  // p0(topleft) * filter(0)
   1521        vmlal.s16       q2,  d26, d2[1]  // p5(left[0]) * filter(5)
   1522        vmlal.s16       q2,  d28, d2[0]  // p6(left[1]) * filter(6)
   1523        vmull.s16       q3,  d19, d0[0]  // p1(top[0]) * filter(1)
   1524        vmlal.s16       q3,  d21, d0[1]  // p2(top[1]) * filter(2)
   1525        vmlal.s16       q3,  d23, d0[2]  // p3(top[2]) * filter(3)
   1526        vmlal.s16       q3,  d25, d0[3]  // p4(top[3]) * filter(4)
   1527        vmlal.s16       q3,  d17, d2[2]  // p0(topleft) * filter(0)
   1528        vmlal.s16       q3,  d27, d2[1]  // p5(left[0]) * filter(5)
   1529        vmlal.s16       q3,  d29, d2[0]  // p6(left[1]) * filter(6)
   1530        vqrshrun.s32    d4,  q2,  #4
   1531        vmull.s16       q4,  d18, d1[0]  // p1(top[0]) * filter(1)
   1532        vmlal.s16       q4,  d20, d1[1]  // p2(top[1]) * filter(2)
   1533        vmlal.s16       q4,  d22, d1[2]  // p3(top[2]) * filter(3)
   1534        vqrshrun.s32    d5,  q3,  #4
   1535        vmin.s16        q2,  q2,  q15
   1536        vmlal.s16       q4,  d24, d1[3]  // p4(top[3]) * filter(4)
   1537        vmlal.s16       q4,  d16, d0[3]  // p0(topleft) * filter(0)
   1538        vmlal.s16       q4,  d26, d4[3]  // p5(left[0]) * filter(5)
   1539        vmlal.s16       q4,  d28, d5[3]  // p6(left[1]) * filter(6)
   1540        vmull.s16       q5,  d19, d1[0]  // p1(top[0]) * filter(1)
   1541        vmlal.s16       q5,  d21, d1[1]  // p2(top[1]) * filter(2)
   1542        vmlal.s16       q5,  d23, d1[2]  // p3(top[2]) * filter(3)
   1543        vmlal.s16       q5,  d25, d1[3]  // p4(top[3]) * filter(4)
   1544        vmlal.s16       q5,  d17, d0[3]  // p0(topleft) * filter(0)
   1545        vmlal.s16       q5,  d27, d4[3]  // p5(left[0]) * filter(5)
   1546        vmlal.s16       q5,  d29, d5[3]  // p6(left[1]) * filter(6)
   1547        vqrshrun.s32    d6,  q4,  #4
   1548        vqrshrun.s32    d7,  q5,  #4
   1549 .endif
   1550        vmin.s16        q3,  q3,  q15
   1551        vswp            d5,  d6
   1552        subs            r4,  r4,  #2
   1553        vst1.16         {q2}, [r0, :128], r1
   1554        vmov            q0,  q3
   1555        vst1.16         {q3}, [r6, :128], r1
   1556        bgt             8b
   1557        vpop            {q4-q7}
   1558        pop             {r4-r8, pc}
   1559 160:
   1560 320:
   1561        sub             r1,  r1,  r3, lsl #1
   1562        mov             lr,  r3
   1563 
   1564 1:
   1565        vld1.16         {d0}, [r2], r7   // left (0-1) + topleft (2)
   1566 2:
   1567        vld1.16         {q1, q2}, [r8]!  // top(0-15)
   1568 .if \bpc == 10
   1569        vmul.i16        q3,  q8,  d0[2]  // p0(topleft) * filter(0)
   1570        vmla.i16        q3,  q13, d0[1]  // p5(left[0]) * filter(5)
   1571        vmla.i16        q3,  q14, d0[0]  // p6(left[1]) * filter(6)
   1572        vmla.i16        q3,  q9,  d2[0]  // p1(top[0]) * filter(1)
   1573        vmla.i16        q3,  q10, d2[1]  // p2(top[1]) * filter(2)
   1574        vmla.i16        q3,  q11, d2[2]  // p3(top[2]) * filter(3)
   1575        vmla.i16        q3,  q12, d2[3]  // p4(top[3]) * filter(4)
   1576 
   1577        vmul.i16        q4,  q9,  d3[0]  // p1(top[0]) * filter(1)
   1578        vmla.i16        q4,  q10, d3[1]  // p2(top[1]) * filter(2)
   1579        vmla.i16        q4,  q11, d3[2]  // p3(top[2]) * filter(3)
   1580        vrshr.s16       q3,  q3,  #4
   1581        vmax.s16        q3,  q3,  q7
   1582        vmin.s16        q3,  q3,  q15
   1583        vmla.i16        q4,  q12, d3[3]  // p4(top[3]) * filter(4)
   1584        vmla.i16        q4,  q8,  d2[3]  // p0(topleft) * filter(0)
   1585        vmla.i16        q4,  q13, d6[3]  // p5(left[0]) * filter(5)
   1586        vmla.i16        q4,  q14, d7[3]  // p6(left[1]) * filter(6)
   1587 
   1588        vmul.i16        q5,  q9,  d4[0]  // p1(top[0]) * filter(1)
   1589        vmla.i16        q5,  q10, d4[1]  // p2(top[1]) * filter(2)
   1590        vmla.i16        q5,  q11, d4[2]  // p3(top[2]) * filter(3)
   1591        vrshr.s16       q4,  q4,  #4
   1592        vmax.s16        q4,  q4,  q7
   1593        vmin.s16        q4,  q4,  q15
   1594        vmov            q0,  q4
   1595        vmla.i16        q5,  q12, d4[3]  // p4(top[3]) * filter(4)
   1596        vmla.i16        q5,  q8,  d3[3]  // p0(topleft) * filter(0)
   1597        vmla.i16        q5,  q13, d0[3]  // p5(left[0]) * filter(5)
   1598        vmla.i16        q5,  q14, d1[3]  // p6(left[1]) * filter(6)
   1599 
   1600        vmul.i16        q6,  q9,  d5[0]  // p1(top[0]) * filter(1)
   1601        vmla.i16        q6,  q10, d5[1]  // p2(top[1]) * filter(2)
   1602        vmla.i16        q6,  q11, d5[2]  // p3(top[2]) * filter(3)
   1603        vrshr.s16       q5,  q5,  #4
   1604        vmax.s16        q5,  q5,  q7
   1605        vmin.s16        q5,  q5,  q15
   1606        vmov            q0,  q5
   1607        vmov.u16        r12, d5[3]
   1608        vmla.i16        q6,  q12, d5[3]  // p4(top[3]) * filter(4)
   1609        vmla.i16        q6,  q8,  d4[3]  // p0(topleft) * filter(0)
   1610        vmla.i16        q6,  q13, d0[3]  // p5(left[0]) * filter(5)
   1611        vmla.i16        q6,  q14, d1[3]  // p6(left[1]) * filter(6)
   1612        vmov.16         d0[2], r12
   1613        subs            r3,  r3,  #16
   1614        vrshr.s16       q6,  q6,  #4
   1615 .else
   1616        vmull.s16       q3,  d16, d0[2]  // p0(topleft) * filter(0)
   1617        vmlal.s16       q3,  d26, d0[1]  // p5(left[0]) * filter(5)
   1618        vmlal.s16       q3,  d28, d0[0]  // p6(left[1]) * filter(6)
   1619        vmlal.s16       q3,  d18, d2[0]  // p1(top[0]) * filter(1)
   1620        vmlal.s16       q3,  d20, d2[1]  // p2(top[1]) * filter(2)
   1621        vmlal.s16       q3,  d22, d2[2]  // p3(top[2]) * filter(3)
   1622        vmlal.s16       q3,  d24, d2[3]  // p4(top[3]) * filter(4)
   1623        vmull.s16       q4,  d17, d0[2]  // p0(topleft) * filter(0)
   1624        vmlal.s16       q4,  d27, d0[1]  // p5(left[0]) * filter(5)
   1625        vmlal.s16       q4,  d29, d0[0]  // p6(left[1]) * filter(6)
   1626        vmlal.s16       q4,  d19, d2[0]  // p1(top[0]) * filter(1)
   1627        vmlal.s16       q4,  d21, d2[1]  // p2(top[1]) * filter(2)
   1628        vmlal.s16       q4,  d23, d2[2]  // p3(top[2]) * filter(3)
   1629        vmlal.s16       q4,  d25, d2[3]  // p4(top[3]) * filter(4)
   1630        vqrshrun.s32    d6,  q3,  #4
   1631        vmull.s16       q5,  d18, d3[0]  // p1(top[0]) * filter(1)
   1632        vmlal.s16       q5,  d20, d3[1]  // p2(top[1]) * filter(2)
   1633        vqrshrun.s32    d7,  q4,  #4
   1634        vmin.s16        q3,  q3,  q15
   1635        vmlal.s16       q5,  d22, d3[2]  // p3(top[2]) * filter(3)
   1636        vmlal.s16       q5,  d24, d3[3]  // p4(top[3]) * filter(4)
   1637        vmlal.s16       q5,  d16, d2[3]  // p0(topleft) * filter(0)
   1638        vmlal.s16       q5,  d26, d6[3]  // p5(left[0]) * filter(5)
   1639        vmlal.s16       q5,  d28, d7[3]  // p6(left[1]) * filter(6)
   1640        vmull.s16       q6,  d19, d3[0]  // p1(top[0]) * filter(1)
   1641        vmlal.s16       q6,  d21, d3[1]  // p2(top[1]) * filter(2)
   1642        vmlal.s16       q6,  d23, d3[2]  // p3(top[2]) * filter(3)
   1643        vmlal.s16       q6,  d25, d3[3]  // p4(top[3]) * filter(4)
   1644        vmlal.s16       q6,  d17, d2[3]  // p0(topleft) * filter(0)
   1645        vmlal.s16       q6,  d27, d6[3]  // p5(left[0]) * filter(5)
   1646        vmlal.s16       q6,  d29, d7[3]  // p6(left[1]) * filter(6)
   1647        vqrshrun.s32    d8,  q5,  #4
   1648        vmull.s16       q7,  d18, d4[0]  // p1(top[0]) * filter(1)
   1649        vmlal.s16       q7,  d20, d4[1]  // p2(top[1]) * filter(2)
   1650        vmlal.s16       q7,  d22, d4[2]  // p3(top[2]) * filter(3)
   1651        vqrshrun.s32    d9,  q6,  #4
   1652        vmin.s16        q0,  q4,  q15
   1653        vmlal.s16       q7,  d24, d4[3]  // p4(top[3]) * filter(4)
   1654        vmlal.s16       q7,  d16, d3[3]  // p0(topleft) * filter(0)
   1655        vmlal.s16       q7,  d26, d0[3]  // p5(left[0]) * filter(5)
   1656        vmlal.s16       q7,  d28, d1[3]  // p6(left[1]) * filter(6)
   1657        vmin.s16        q4,  q4,  q15
   1658        vmull.s16       q6,  d19, d4[0]  // p1(top[0]) * filter(1)
   1659        vmlal.s16       q6,  d21, d4[1]  // p2(top[1]) * filter(2)
   1660        vmlal.s16       q6,  d23, d4[2]  // p3(top[2]) * filter(3)
   1661        vmlal.s16       q6,  d25, d4[3]  // p4(top[3]) * filter(4)
   1662        vmlal.s16       q6,  d17, d3[3]  // p0(topleft) * filter(0)
   1663        vmlal.s16       q6,  d27, d0[3]  // p5(left[0]) * filter(5)
   1664        vmlal.s16       q6,  d29, d1[3]  // p6(left[1]) * filter(6)
   1665        vqrshrun.s32    d10, q7,  #4
   1666        vmull.s16       q1,  d18, d5[0]  // p1(top[0]) * filter(1)
   1667        vmlal.s16       q1,  d20, d5[1]  // p2(top[1]) * filter(2)
   1668        vmlal.s16       q1,  d22, d5[2]  // p3(top[2]) * filter(3)
   1669        vqrshrun.s32    d11, q6,  #4
   1670        vmin.s16        q0,  q5,  q15
   1671        vmlal.s16       q1,  d24, d5[3]  // p4(top[3]) * filter(4)
   1672        vmlal.s16       q1,  d16, d4[3]  // p0(topleft) * filter(0)
   1673        vmlal.s16       q1,  d26, d0[3]  // p5(left[0]) * filter(5)
   1674        vmlal.s16       q1,  d28, d1[3]  // p6(left[1]) * filter(6)
   1675        vmin.s16        q5,  q5,  q15
   1676        vmov.u16        r12, d5[3]
   1677        vmull.s16       q7,  d19, d5[0]  // p1(top[0]) * filter(1)
   1678        vmlal.s16       q7,  d21, d5[1]  // p2(top[1]) * filter(2)
   1679        vmlal.s16       q7,  d23, d5[2]  // p3(top[2]) * filter(3)
   1680        vmlal.s16       q7,  d25, d5[3]  // p4(top[3]) * filter(4)
   1681        vmlal.s16       q7,  d17, d4[3]  // p0(topleft) * filter(0)
   1682        vmlal.s16       q7,  d27, d0[3]  // p5(left[0]) * filter(5)
   1683        vmlal.s16       q7,  d29, d1[3]  // p6(left[1]) * filter(6)
   1684        vmov.16         d0[2], r12
   1685        vqrshrun.s32    d12, q1,  #4
   1686        subs            r3,  r3,  #16
   1687        vqrshrun.s32    d13, q7,  #4
   1688 .endif
   1689        vswp            q4,  q5
   1690 .if \bpc == 10
   1691        vmax.s16        q6,  q6,  q7
   1692 .endif
   1693        vswp            d7,  d10
   1694        vmin.s16        q6,  q6,  q15
   1695 
   1696        vswp            d9,  d12
   1697 
   1698        vst1.16         {q3, q4}, [r0, :128]!
   1699        vst1.16         {q5, q6}, [r6, :128]!
   1700        ble             8f
   1701        vmov.u16        r12, d13[3]
   1702        vmov.16         d0[0], r12
   1703        vmov.u16        r12, d9[3]
   1704        vmov.16         d0[1], r12
   1705        b               2b
   1706 8:
   1707        subs            r4,  r4,  #2
   1708 
   1709        ble             9f
   1710        sub             r8,  r6,  lr, lsl #1
   1711        add             r0,  r0,  r1
   1712        add             r6,  r6,  r1
   1713        mov             r3,  lr
   1714        b               1b
   1715 9:
   1716        vpop            {q4-q7}
   1717        pop             {r4-r8, pc}
   1718 endfunc
   1719 .endm
   1720 
   1721 filter_fn 10
   1722 filter_fn 12
   1723 
   1724 function ipred_filter_16bpc_neon, export=1
   1725        push            {r4-r8, lr}
   1726        vpush           {q4-q7}
   1727        movw            r12, 0x3ff
   1728        ldr             r8, [sp, #104]
   1729        cmp             r8,  r12
   1730        ble             ipred_filter_10bpc_neon
   1731        b               ipred_filter_12bpc_neon
   1732 endfunc
   1733 
   1734 // void pal_pred_16bpc_neon(pixel *dst, const ptrdiff_t stride,
   1735 //                          const pixel *const pal, const uint8_t *idx,
   1736 //                          const int w, const int h);
   1737 function pal_pred_16bpc_neon, export=1
   1738        push            {r4-r5, lr}
   1739        ldr             r4,  [sp, #12]
   1740        ldr             r5,  [sp, #16]
   1741        vld1.16         {q14}, [r2, :128]
   1742        clz             lr,  r4
   1743        adr             r12, L(pal_pred_tbl)
   1744        sub             lr,  lr,  #25
   1745        vmov.i8         q13, #7
   1746        ldr             lr,  [r12, lr, lsl #2]
   1747        vmov.i16        q15, #0x100
   1748        add             r12, r12, lr
   1749        add             r2,  r0,  r1
   1750        bx              r12
   1751 
   1752        .align 2
   1753 L(pal_pred_tbl):
   1754        .word 640f - L(pal_pred_tbl) + CONFIG_THUMB
   1755        .word 320f - L(pal_pred_tbl) + CONFIG_THUMB
   1756        .word 160f - L(pal_pred_tbl) + CONFIG_THUMB
   1757        .word 80f  - L(pal_pred_tbl) + CONFIG_THUMB
   1758        .word 40f  - L(pal_pred_tbl) + CONFIG_THUMB
   1759 
   1760 40:
   1761        lsl             r1,  r1,  #1
   1762 4:
   1763        vld1.8          {d2}, [r3, :64]!
   1764        subs            r5,  r5,  #4
   1765        vshr.u8         d3,  d2,  #4
   1766        vand.u8         d2,  d2,  d26
   1767        vzip.8          d2,  d3
   1768        // Restructure q1 from a, b, c, ... into 2*a, 2*a+1, 2*b, 2*b+1, 2*c, 2*c+1, ...
   1769        vadd.i8         q0,  q1,  q1
   1770        vadd.i8         q1,  q1,  q1
   1771        vzip.8          q0,  q1
   1772        vadd.i16        q0,  q0,  q15
   1773        vadd.i16        q1,  q1,  q15
   1774        vtbl.8          d0, {q14}, d0
   1775        vtbl.8          d1, {q14}, d1
   1776        vst1.16         {d0}, [r0, :64], r1
   1777        vtbl.8          d2, {q14}, d2
   1778        vst1.16         {d1}, [r2, :64], r1
   1779        vtbl.8          d3, {q14}, d3
   1780        vst1.16         {d2}, [r0, :64], r1
   1781        vst1.16         {d3}, [r2, :64], r1
   1782        bgt             4b
   1783        pop             {r4-r5, pc}
   1784 80:
   1785        lsl             r1,  r1,  #1
   1786 8:
   1787        vld1.8          {q1}, [r3, :64]!
   1788        subs            r5,  r5,  #4
   1789        vshr.u8         q2,  q1,  #4
   1790        vand.u8         q1,  q1,  q13
   1791        vzip.8          q1,  q2
   1792        // Prefer doing the adds twice, instead of chaining a vmov after
   1793        // the add.
   1794        vadd.i8         q0,  q1,  q1
   1795        vadd.i8         q1,  q1,  q1
   1796        vadd.i8         q3,  q2,  q2
   1797        vadd.i8         q2,  q2,  q2
   1798        vzip.8          q0,  q1
   1799        vzip.8          q2,  q3
   1800        vadd.i16        q0,  q0,  q15
   1801        vadd.i16        q1,  q1,  q15
   1802        vtbl.8          d0, {q14}, d0
   1803        vadd.i16        q2,  q2,  q15
   1804        vtbl.8          d1, {q14}, d1
   1805        vadd.i16        q3,  q3,  q15
   1806        vtbl.8          d2, {q14}, d2
   1807        vtbl.8          d3, {q14}, d3
   1808        vtbl.8          d4, {q14}, d4
   1809        vtbl.8          d5, {q14}, d5
   1810        vst1.16         {q0}, [r0, :128], r1
   1811        vtbl.8          d6, {q14}, d6
   1812        vst1.16         {q1}, [r2, :128], r1
   1813        vtbl.8          d7, {q14}, d7
   1814        vst1.16         {q2}, [r0, :128], r1
   1815        vst1.16         {q3}, [r2, :128], r1
   1816        bgt             8b
   1817        pop             {r4-r5, pc}
   1818 160:
   1819        lsl             r1,  r1,  #1
   1820 16:
   1821        vld1.8          {q10, q11}, [r3, :64]!
   1822        subs            r5,  r5,  #4
   1823        vand.u8         q2,  q10, q13
   1824        vshr.u8         q3,  q10, #4
   1825        vand.u8         q10, q11, q13
   1826        vshr.u8         q11, q11, #4
   1827        vzip.8          q2,  q3
   1828        vzip.8          q10, q11
   1829        vadd.i8         q0,  q2,  q2
   1830        vadd.i8         q1,  q2,  q2
   1831        vadd.i8         q2,  q3,  q3
   1832        vadd.i8         q3,  q3,  q3
   1833        vadd.i8         q8,  q10, q10
   1834        vadd.i8         q9,  q10, q10
   1835        vadd.i8         q10, q11, q11
   1836        vzip.8          q0,  q1
   1837        vadd.i8         q11, q11, q11
   1838        vzip.8          q2,  q3
   1839        vzip.8          q8,  q9
   1840        vadd.i16        q0,  q0,  q15
   1841        vzip.8          q10, q11
   1842        vadd.i16        q1,  q1,  q15
   1843        vadd.i16        q2,  q2,  q15
   1844        vadd.i16        q3,  q3,  q15
   1845        vadd.i16        q8,  q8,  q15
   1846        vadd.i16        q9,  q9,  q15
   1847        vadd.i16        q10, q10, q15
   1848        vtbl.8          d0,  {q14}, d0
   1849        vadd.i16        q11, q11, q15
   1850        vtbl.8          d1,  {q14}, d1
   1851        vtbl.8          d2,  {q14}, d2
   1852        vtbl.8          d3,  {q14}, d3
   1853        vtbl.8          d4,  {q14}, d4
   1854        vtbl.8          d5,  {q14}, d5
   1855        vtbl.8          d6,  {q14}, d6
   1856        vtbl.8          d7,  {q14}, d7
   1857        vtbl.8          d16, {q14}, d16
   1858        vtbl.8          d17, {q14}, d17
   1859        vtbl.8          d18, {q14}, d18
   1860        vst1.16         {q0,  q1},  [r0, :128], r1
   1861        vtbl.8          d19, {q14}, d19
   1862        vtbl.8          d20, {q14}, d20
   1863        vst1.16         {q2,  q3},  [r2, :128], r1
   1864        vtbl.8          d21, {q14}, d21
   1865        vtbl.8          d22, {q14}, d22
   1866        vst1.16         {q8,  q9},  [r0, :128], r1
   1867        vtbl.8          d23, {q14}, d23
   1868        vst1.16         {q10, q11}, [r2, :128], r1
   1869        bgt             16b
   1870        pop             {r4-r5, pc}
   1871 320:
   1872        lsl             r1,  r1,  #1
   1873        sub             r1,  r1,  #32
   1874 32:
   1875        vld1.8          {q10, q11}, [r3, :64]!
   1876        subs            r5,  r5,  #2
   1877        vand.u8         q2,  q10, q13
   1878        vshr.u8         q3,  q10, #4
   1879        vand.u8         q10, q11, q13
   1880        vshr.u8         q11, q11, #4
   1881        vzip.8          q2,  q3
   1882        vzip.8          q10, q11
   1883        vadd.i8         q0,  q2,  q2
   1884        vadd.i8         q1,  q2,  q2
   1885        vadd.i8         q2,  q3,  q3
   1886        vadd.i8         q3,  q3,  q3
   1887        vadd.i8         q8,  q10, q10
   1888        vadd.i8         q9,  q10, q10
   1889        vadd.i8         q10, q11, q11
   1890        vzip.8          q0,  q1
   1891        vadd.i8         q11, q11, q11
   1892        vzip.8          q2,  q3
   1893        vzip.8          q8,  q9
   1894        vadd.i16        q0,  q0,  q15
   1895        vzip.8          q10, q11
   1896        vadd.i16        q1,  q1,  q15
   1897        vadd.i16        q2,  q2,  q15
   1898        vadd.i16        q3,  q3,  q15
   1899        vadd.i16        q8,  q8,  q15
   1900        vadd.i16        q9,  q9,  q15
   1901        vadd.i16        q10, q10, q15
   1902        vtbl.8          d0,  {q14}, d0
   1903        vadd.i16        q11, q11, q15
   1904        vtbl.8          d1,  {q14}, d1
   1905        vtbl.8          d2,  {q14}, d2
   1906        vtbl.8          d3,  {q14}, d3
   1907        vtbl.8          d4,  {q14}, d4
   1908        vtbl.8          d5,  {q14}, d5
   1909        vtbl.8          d6,  {q14}, d6
   1910        vtbl.8          d7,  {q14}, d7
   1911        vtbl.8          d16, {q14}, d16
   1912        vtbl.8          d17, {q14}, d17
   1913        vtbl.8          d18, {q14}, d18
   1914        vst1.16         {q0,  q1},  [r0, :128]!
   1915        vtbl.8          d19, {q14}, d19
   1916        vtbl.8          d20, {q14}, d20
   1917        vst1.16         {q2,  q3},  [r0, :128], r1
   1918        vtbl.8          d21, {q14}, d21
   1919        vtbl.8          d22, {q14}, d22
   1920        vst1.16         {q8,  q9},  [r2, :128]!
   1921        vtbl.8          d23, {q14}, d23
   1922        vst1.16         {q10, q11}, [r2, :128], r1
   1923        bgt             32b
   1924        pop             {r4-r5, pc}
   1925 640:
   1926        sub             r1,  r1,  #96
   1927 64:
   1928        vld1.8          {q10, q11}, [r3, :64]!
   1929        subs            r5,  r5,  #1
   1930        vand.u8         q2,  q10, q13
   1931        vshr.u8         q3,  q10, #4
   1932        vand.u8         q10, q11, q13
   1933        vshr.u8         q11, q11, #4
   1934        vzip.8          q2,  q3
   1935        vzip.8          q10, q11
   1936        vadd.i8         q0,  q2,  q2
   1937        vadd.i8         q1,  q2,  q2
   1938        vadd.i8         q2,  q3,  q3
   1939        vadd.i8         q3,  q3,  q3
   1940        vadd.i8         q8,  q10, q10
   1941        vadd.i8         q9,  q10, q10
   1942        vadd.i8         q10, q11, q11
   1943        vzip.8          q0,  q1
   1944        vadd.i8         q11, q11, q11
   1945        vzip.8          q2,  q3
   1946        vzip.8          q8,  q9
   1947        vadd.i16        q0,  q0,  q15
   1948        vzip.8          q10, q11
   1949        vadd.i16        q1,  q1,  q15
   1950        vadd.i16        q2,  q2,  q15
   1951        vadd.i16        q3,  q3,  q15
   1952        vadd.i16        q8,  q8,  q15
   1953        vadd.i16        q9,  q9,  q15
   1954        vadd.i16        q10, q10, q15
   1955        vtbl.8          d0,  {q14}, d0
   1956        vadd.i16        q11, q11, q15
   1957        vtbl.8          d1,  {q14}, d1
   1958        vtbl.8          d2,  {q14}, d2
   1959        vtbl.8          d3,  {q14}, d3
   1960        vtbl.8          d4,  {q14}, d4
   1961        vtbl.8          d5,  {q14}, d5
   1962        vtbl.8          d6,  {q14}, d6
   1963        vtbl.8          d7,  {q14}, d7
   1964        vtbl.8          d16, {q14}, d16
   1965        vtbl.8          d17, {q14}, d17
   1966        vtbl.8          d18, {q14}, d18
   1967        vst1.16         {q0,  q1},  [r0, :128]!
   1968        vtbl.8          d19, {q14}, d19
   1969        vtbl.8          d20, {q14}, d20
   1970        vst1.16         {q2,  q3},  [r0, :128]!
   1971        vtbl.8          d21, {q14}, d21
   1972        vtbl.8          d22, {q14}, d22
   1973        vst1.16         {q8,  q9},  [r0, :128]!
   1974        vtbl.8          d23, {q14}, d23
   1975        vst1.16         {q10, q11}, [r0, :128], r1
   1976        bgt             64b
   1977        pop             {r4-r5, pc}
   1978 endfunc
   1979 
   1980 // void ipred_cfl_128_16bpc_neon(pixel *dst, const ptrdiff_t stride,
   1981 //                               const pixel *const topleft,
   1982 //                               const int width, const int height,
   1983 //                               const int16_t *ac, const int alpha,
   1984 //                               const int bitdepth_max);
   1985 function ipred_cfl_128_16bpc_neon, export=1
   1986        push            {r4-r8, lr}
   1987        ldrd            r4,  r5,  [sp, #24]
   1988        ldrd            r6,  r7,  [sp, #32]
   1989        clz             lr,  r3
   1990        vdup.16         q15, r7       // bitdepth_max
   1991        adr             r12, L(ipred_cfl_128_tbl)
   1992        sub             lr,  lr,  #26
   1993        ldr             lr,  [r12, lr, lsl #2]
   1994        vrshr.u16       q0,  q15, #1
   1995        vdup.16         q1,  r6       // alpha
   1996        add             r12, r12, lr
   1997        add             r6,  r0,  r1
   1998        lsl             r1,  r1,  #1
   1999        vmov.i16        q14, #0
   2000        bx              r12
   2001 
   2002        .align 2
   2003 L(ipred_cfl_128_tbl):
   2004 L(ipred_cfl_splat_tbl):
   2005        .word L(ipred_cfl_splat_w16) - L(ipred_cfl_128_tbl) + CONFIG_THUMB
   2006        .word L(ipred_cfl_splat_w16) - L(ipred_cfl_128_tbl) + CONFIG_THUMB
   2007        .word L(ipred_cfl_splat_w8)  - L(ipred_cfl_128_tbl) + CONFIG_THUMB
   2008        .word L(ipred_cfl_splat_w4)  - L(ipred_cfl_128_tbl) + CONFIG_THUMB
   2009 
   2010 L(ipred_cfl_splat_w4):
   2011        vld1.16         {q8, q9}, [r5, :128]!
   2012        vmull.s16       q2,  d16, d2  // diff = ac * alpha
   2013        vmull.s16       q3,  d17, d3
   2014        vmull.s16       q8,  d18, d2
   2015        vmull.s16       q9,  d19, d3
   2016        vshr.s32        q10, q2,  #31 // sign = diff >> 15
   2017        vshr.s32        q11, q3,  #31
   2018        vshr.s32        q12, q8,  #31
   2019        vshr.s32        q13, q9,  #31
   2020        vadd.i32        q2,  q2,  q10 // diff + sign
   2021        vadd.i32        q3,  q3,  q11
   2022        vadd.i32        q8,  q8,  q12
   2023        vadd.i32        q9,  q9,  q13
   2024        vrshrn.i32      d4,  q2,  #6  // (diff + sign + 32) >> 6 = apply_sign()
   2025        vrshrn.i32      d5,  q3,  #6
   2026        vrshrn.i32      d6,  q8,  #6
   2027        vrshrn.i32      d7,  q9,  #6
   2028        vadd.i16        q2,  q2,  q0  // dc + apply_sign()
   2029        vadd.i16        q3,  q3,  q0
   2030        vmax.s16        q2,  q2,  q14
   2031        vmax.s16        q3,  q3,  q14
   2032        vmin.s16        q2,  q2,  q15
   2033        vmin.s16        q3,  q3,  q15
   2034        vst1.16         {d4}, [r0, :64], r1
   2035        vst1.16         {d5}, [r6, :64], r1
   2036        subs            r4,  r4,  #4
   2037        vst1.16         {d6}, [r0, :64], r1
   2038        vst1.16         {d7}, [r6, :64], r1
   2039        bgt             L(ipred_cfl_splat_w4)
   2040        pop             {r4-r8, pc}
   2041 L(ipred_cfl_splat_w8):
   2042        vld1.16         {q8, q9}, [r5, :128]!
   2043        subs            r4,  r4,  #2
   2044        vmull.s16       q2,  d16, d2  // diff = ac * alpha
   2045        vmull.s16       q3,  d17, d3
   2046        vmull.s16       q8,  d18, d2
   2047        vmull.s16       q9,  d19, d3
   2048        vshr.s32        q10, q2,  #31 // sign = diff >> 15
   2049        vshr.s32        q11, q3,  #31
   2050        vshr.s32        q12, q8,  #31
   2051        vshr.s32        q13, q9,  #31
   2052        vadd.i32        q2,  q2,  q10 // diff + sign
   2053        vadd.i32        q3,  q3,  q11
   2054        vadd.i32        q8,  q8,  q12
   2055        vadd.i32        q9,  q9,  q13
   2056        vrshrn.i32      d4,  q2,  #6  // (diff + sign + 32) >> 6 = apply_sign()
   2057        vrshrn.i32      d5,  q3,  #6
   2058        vrshrn.i32      d6,  q8,  #6
   2059        vrshrn.i32      d7,  q9,  #6
   2060        vadd.i16        q2,  q2,  q0  // dc + apply_sign()
   2061        vadd.i16        q3,  q3,  q0
   2062        vmax.s16        q2,  q2,  q14
   2063        vmax.s16        q3,  q3,  q14
   2064        vmin.s16        q2,  q2,  q15
   2065        vmin.s16        q3,  q3,  q15
   2066        vst1.16         {q2}, [r0, :128], r1
   2067        vst1.16         {q3}, [r6, :128], r1
   2068        bgt             L(ipred_cfl_splat_w8)
   2069        pop             {r4-r8, pc}
   2070 L(ipred_cfl_splat_w16):
   2071        vpush           {q4-q7}
   2072        add             r12, r5,  r3, lsl #1
   2073        sub             r1,  r1,  r3, lsl #1
   2074        mov             lr,  r3
   2075 1:
   2076        vld1.16         {q6, q7}, [r5, :128]!
   2077        vmull.s16       q2,  d12, d2  // diff = ac * alpha
   2078        vld1.16         {q8, q9}, [r12, :128]!
   2079        vmull.s16       q3,  d13, d3
   2080        vmull.s16       q4,  d14, d2
   2081        vmull.s16       q5,  d15, d3
   2082        vmull.s16       q6,  d16, d2
   2083        vmull.s16       q7,  d17, d3
   2084        vmull.s16       q8,  d18, d2
   2085        vmull.s16       q9,  d19, d3
   2086        vshr.s32        q10, q2,  #31 // sign = diff >> 15
   2087        vshr.s32        q11, q3,  #31
   2088        vshr.s32        q12, q4,  #31
   2089        vshr.s32        q13, q5,  #31
   2090        vadd.i32        q2,  q2,  q10 // diff + sign
   2091        vshr.s32        q10, q6,  #31
   2092        vadd.i32        q3,  q3,  q11
   2093        vshr.s32        q11, q7,  #31
   2094        vadd.i32        q4,  q4,  q12
   2095        vshr.s32        q12, q8,  #31
   2096        vadd.i32        q5,  q5,  q13
   2097        vshr.s32        q13, q9,  #31
   2098        vadd.i32        q6,  q6,  q10
   2099        vadd.i32        q7,  q7,  q11
   2100        vadd.i32        q8,  q8,  q12
   2101        vadd.i32        q9,  q9,  q13
   2102        vrshrn.i32      d4,  q2,  #6  // (diff + sign + 32) >> 6 = apply_sign()
   2103        vrshrn.i32      d5,  q3,  #6
   2104        vrshrn.i32      d6,  q4,  #6
   2105        vrshrn.i32      d7,  q5,  #6
   2106        vadd.i16        q2,  q2,  q0  // dc + apply_sign()
   2107        vrshrn.i32      d8,  q6,  #6
   2108        vrshrn.i32      d9,  q7,  #6
   2109        vadd.i16        q3,  q3,  q0
   2110        vrshrn.i32      d10, q8,  #6
   2111        vrshrn.i32      d11, q9,  #6
   2112        vadd.i16        q4,  q4,  q0
   2113        vadd.i16        q5,  q5,  q0
   2114        vmax.s16        q2,  q2,  q14
   2115        vmax.s16        q3,  q3,  q14
   2116        vmax.s16        q4,  q4,  q14
   2117        vmax.s16        q5,  q5,  q14
   2118        vmin.s16        q2,  q2,  q15
   2119        vmin.s16        q3,  q3,  q15
   2120        vmin.s16        q4,  q4,  q15
   2121        vmin.s16        q5,  q5,  q15
   2122        subs            r3,  r3,  #16
   2123        vst1.16         {q2, q3}, [r0, :128]!
   2124        vst1.16         {q4, q5}, [r6, :128]!
   2125        bgt             1b
   2126        subs            r4,  r4,  #2
   2127        add             r5,  r5,  lr, lsl #1
   2128        add             r12, r12, lr, lsl #1
   2129        add             r0,  r0,  r1
   2130        add             r6,  r6,  r1
   2131        mov             r3,  lr
   2132        bgt             1b
   2133        vpop            {q4-q7}
   2134        pop             {r4-r8, pc}
   2135 endfunc
   2136 
   2137 // void ipred_cfl_top_16bpc_neon(pixel *dst, const ptrdiff_t stride,
   2138 //                               const pixel *const topleft,
   2139 //                               const int width, const int height,
   2140 //                               const int16_t *ac, const int alpha,
   2141 //                               const int bitdepth_max);
   2142 function ipred_cfl_top_16bpc_neon, export=1
   2143        push            {r4-r8, lr}
   2144        ldrd            r4,  r5,  [sp, #24]
   2145        ldrd            r6,  r7,  [sp, #32]
   2146        clz             lr,  r3
   2147        vdup.16         q15, r7       // bitdepth_max
   2148        adr             r12, L(ipred_cfl_top_tbl)
   2149        sub             lr,  lr,  #26
   2150        ldr             lr,  [r12, lr, lsl #2]
   2151        vdup.16         q1,  r6   // alpha
   2152        add             r2,  r2,  #2
   2153        add             r12, r12, lr
   2154        add             r6,  r0,  r1
   2155        lsl             r1,  r1,  #1
   2156        vmov.i16        q14, #0
   2157        bx              r12
   2158 
   2159        .align 2
   2160 L(ipred_cfl_top_tbl):
   2161        .word 32f - L(ipred_cfl_top_tbl) + CONFIG_THUMB
   2162        .word 16f - L(ipred_cfl_top_tbl) + CONFIG_THUMB
   2163        .word 8f  - L(ipred_cfl_top_tbl) + CONFIG_THUMB
   2164        .word 4f  - L(ipred_cfl_top_tbl) + CONFIG_THUMB
   2165 
   2166 4:
   2167        vld1.16         {d0}, [r2]
   2168        vpadd.i16       d0,  d0,  d0
   2169        vpadd.i16       d0,  d0,  d0
   2170        vrshr.u16       d0,  d0,  #2
   2171        vdup.16         q0,  d0[0]
   2172        b               L(ipred_cfl_splat_w4)
   2173 8:
   2174        vld1.16         {q0}, [r2]
   2175        vadd.i16        d0,  d0,  d1
   2176        vpadd.i16       d0,  d0,  d0
   2177        vpadd.i16       d0,  d0,  d0
   2178        vrshr.u16       d0,  d0,  #3
   2179        vdup.16         q0,  d0[0]
   2180        b               L(ipred_cfl_splat_w8)
   2181 16:
   2182        vld1.16         {q2, q3}, [r2]
   2183        vadd.i16        q0,  q2,  q3
   2184        vadd.i16        d0,  d0,  d1
   2185        vpadd.i16       d0,  d0,  d0
   2186        vpadd.i16       d0,  d0,  d0
   2187        vrshr.u16       d0,  d0,  #4
   2188        vdup.16         q0,  d0[0]
   2189        b               L(ipred_cfl_splat_w16)
   2190 32:
   2191        vld1.16         {q8,  q9},  [r2]!
   2192        vld1.16         {q10, q11}, [r2]
   2193        vadd.i16        q8,  q8,  q9
   2194        vadd.i16        q10, q10, q11
   2195        vadd.i16        q0,  q8,  q10
   2196        vadd.i16        d0,  d0,  d1
   2197        vpadd.i16       d0,  d0,  d0
   2198        vpaddl.u16      d0,  d0
   2199        vrshrn.i32      d0,  q0,  #5
   2200        vdup.16         q0,  d0[0]
   2201        b               L(ipred_cfl_splat_w16)
   2202 endfunc
   2203 
   2204 // void ipred_cfl_left_16bpc_neon(pixel *dst, const ptrdiff_t stride,
   2205 //                                const pixel *const topleft,
   2206 //                                const int width, const int height,
   2207 //                                const int16_t *ac, const int alpha,
   2208 //                                const int bitdepth_max);
   2209 function ipred_cfl_left_16bpc_neon, export=1
   2210        push            {r4-r8, lr}
   2211        ldrd            r4,  r5,  [sp, #24]
   2212        ldrd            r6,  r7,  [sp, #32]
   2213        sub             r2,  r2,  r4, lsl #1
   2214        clz             lr,  r3
   2215        clz             r8,  r4
   2216        vdup.16         q15, r7       // bitdepth_max
   2217        adr             r12, L(ipred_cfl_splat_tbl)
   2218        adr             r7,  L(ipred_cfl_left_tbl)
   2219        sub             lr,  lr,  #26
   2220        sub             r8,  r8,  #26
   2221        ldr             lr,  [r12, lr, lsl #2]
   2222        ldr             r8,  [r7,  r8, lsl #2]
   2223        vdup.16         q1,  r6   // alpha
   2224        add             r12, r12, lr
   2225        add             r7,  r7,  r8
   2226        add             r6,  r0,  r1
   2227        lsl             r1,  r1,  #1
   2228        vmov.i16        q14, #0
   2229        bx              r7
   2230 
   2231        .align 2
   2232 L(ipred_cfl_left_tbl):
   2233        .word L(ipred_cfl_left_h32) - L(ipred_cfl_left_tbl) + CONFIG_THUMB
   2234        .word L(ipred_cfl_left_h16) - L(ipred_cfl_left_tbl) + CONFIG_THUMB
   2235        .word L(ipred_cfl_left_h8)  - L(ipred_cfl_left_tbl) + CONFIG_THUMB
   2236        .word L(ipred_cfl_left_h4)  - L(ipred_cfl_left_tbl) + CONFIG_THUMB
   2237 
   2238 L(ipred_cfl_left_h4):
   2239        vld1.16         {d0}, [r2, :64]
   2240        vpadd.i16       d0,  d0,  d0
   2241        vpadd.i16       d0,  d0,  d0
   2242        vrshr.u16       d0,  d0,  #2
   2243        vdup.16         q0,  d0[0]
   2244        bx              r12
   2245 
   2246 L(ipred_cfl_left_h8):
   2247        vld1.16         {q0}, [r2, :128]
   2248        vadd.i16        d0,  d0,  d1
   2249        vpadd.i16       d0,  d0,  d0
   2250        vpadd.i16       d0,  d0,  d0
   2251        vrshr.u16       d0,  d0,  #3
   2252        vdup.16         q0,  d0[0]
   2253        bx              r12
   2254 
   2255 L(ipred_cfl_left_h16):
   2256        vld1.16         {q2, q3}, [r2, :128]
   2257        vadd.i16        q0,  q2,  q3
   2258        vadd.i16        d0,  d0,  d1
   2259        vpadd.i16       d0,  d0,  d0
   2260        vpadd.i16       d0,  d0,  d0
   2261        vrshr.u16       d0,  d0,  #4
   2262        vdup.16         q0,  d0[0]
   2263        bx              r12
   2264 
   2265 L(ipred_cfl_left_h32):
   2266        vld1.16         {q8,  q9},  [r2, :128]!
   2267        vld1.16         {q10, q11}, [r2, :128]
   2268        vadd.i16        q8,  q8,  q9
   2269        vadd.i16        q10, q10, q11
   2270        vadd.i16        q0,  q8,  q10
   2271        vadd.i16        d0,  d0,  d1
   2272        vpadd.i16       d0,  d0,  d0
   2273        vpaddl.u16      d0,  d0
   2274        vrshrn.i32      d0,  q0,  #5
   2275        vdup.16         q0,  d0[0]
   2276        bx              r12
   2277 endfunc
   2278 
   2279 // void ipred_cfl_16bpc_neon(pixel *dst, const ptrdiff_t stride,
   2280 //                           const pixel *const topleft,
   2281 //                           const int width, const int height,
   2282 //                           const int16_t *ac, const int alpha,
   2283 //                           const int bitdepth_max);
   2284 function ipred_cfl_16bpc_neon, export=1
   2285        push            {r4-r8, lr}
   2286        ldrd            r4,  r5,  [sp, #24]
   2287        ldrd            r6,  r7,  [sp, #32]
   2288        sub             r2,  r2,  r4, lsl #1
   2289        add             r8,  r3,  r4  // width + height
   2290        vdup.16         q1,  r6       // alpha
   2291        clz             lr,  r3
   2292        clz             r6,  r4
   2293        vdup.32         d16, r8       // width + height
   2294        vdup.16         q15, r7       // bitdepth_max
   2295        adr             r7,  L(ipred_cfl_tbl)
   2296        rbit            r8,  r8       // rbit(width + height)
   2297        sub             lr,  lr,  #22 // 26 leading bits, minus table offset 4
   2298        sub             r6,  r6,  #26
   2299        clz             r8,  r8       // ctz(width + height)
   2300        ldr             lr,  [r7, lr, lsl #2]
   2301        ldr             r6,  [r7, r6, lsl #2]
   2302        neg             r8,  r8       // -ctz(width + height)
   2303        add             r12, r7,  lr
   2304        add             r7,  r7,  r6
   2305        vshr.u32        d16, d16, #1  // (width + height) >> 1
   2306        vdup.32         d17, r8       // -ctz(width + height)
   2307        add             r6,  r0,  r1
   2308        lsl             r1,  r1,  #1
   2309        vmov.i16        q14, #0
   2310        bx              r7
   2311 
   2312        .align 2
   2313 L(ipred_cfl_tbl):
   2314        .word L(ipred_cfl_h32) - L(ipred_cfl_tbl) + CONFIG_THUMB
   2315        .word L(ipred_cfl_h16) - L(ipred_cfl_tbl) + CONFIG_THUMB
   2316        .word L(ipred_cfl_h8)  - L(ipred_cfl_tbl) + CONFIG_THUMB
   2317        .word L(ipred_cfl_h4)  - L(ipred_cfl_tbl) + CONFIG_THUMB
   2318        .word L(ipred_cfl_w32) - L(ipred_cfl_tbl) + CONFIG_THUMB
   2319        .word L(ipred_cfl_w16) - L(ipred_cfl_tbl) + CONFIG_THUMB
   2320        .word L(ipred_cfl_w8)  - L(ipred_cfl_tbl) + CONFIG_THUMB
   2321        .word L(ipred_cfl_w4)  - L(ipred_cfl_tbl) + CONFIG_THUMB
   2322 
   2323 L(ipred_cfl_h4):
   2324        vld1.16         {d0}, [r2, :64]!
   2325        vpadd.i16       d0,  d0,  d0
   2326        add             r2,  r2,  #2
   2327        vpaddl.u16      d0,  d0
   2328        bx              r12
   2329 L(ipred_cfl_w4):
   2330        vld1.16         {d1}, [r2]
   2331        vadd.i32        d0,  d0,  d16
   2332        vpadd.i16       d1,  d1,  d1
   2333        vpaddl.u16      d1,  d1
   2334        cmp             r4,  #4
   2335        vadd.i32        d0,  d0,  d1
   2336        vshl.u32        d0,  d0,  d17
   2337        beq             1f
   2338        // h = 8/16
   2339        cmp             r4,  #16
   2340        movw            lr,  #0x6667
   2341        movw            r8,  #0xAAAB
   2342        it              ne
   2343        movne           lr,  r8
   2344        vdup.32         d18, lr
   2345        vmul.i32        d0,  d0,  d18
   2346        vshr.u32        d0,  d0,  #17
   2347 1:
   2348        vdup.16         q0,  d0[0]
   2349        b               L(ipred_cfl_splat_w4)
   2350 
   2351 L(ipred_cfl_h8):
   2352        vld1.16         {q0}, [r2, :128]!
   2353        vadd.i16        d0,  d0,  d1
   2354        vpadd.i16       d0,  d0,  d0
   2355        add             r2,  r2,  #2
   2356        vpaddl.u16      d0,  d0
   2357        bx              r12
   2358 L(ipred_cfl_w8):
   2359        vld1.16         {q2}, [r2]
   2360        vadd.i32        d0,  d0,  d16
   2361        vadd.i16        d1,  d4,  d5
   2362        vpadd.i16       d1,  d1,  d1
   2363        vpaddl.u16      d1,  d1
   2364        cmp             r4,  #8
   2365        vadd.i32        d0,  d0,  d1
   2366        vshl.u32        d0,  d0,  d17
   2367        beq             1f
   2368        // h = 4/16/32
   2369        cmp             r4,  #32
   2370        movw            lr,  #0x6667
   2371        movw            r8,  #0xAAAB
   2372        it              ne
   2373        movne           lr,  r8
   2374        vdup.32         d18, lr
   2375        vmul.i32        d0,  d0,  d18
   2376        vshr.u32        d0,  d0,  #17
   2377 1:
   2378        vdup.16         q0,  d0[0]
   2379        b               L(ipred_cfl_splat_w8)
   2380 
   2381 L(ipred_cfl_h16):
   2382        vld1.16         {q2, q3}, [r2, :128]!
   2383        vadd.i16        q0,  q2,  q3
   2384        vadd.i16        d0,  d0,  d1
   2385        vpadd.i16       d0,  d0,  d0
   2386        add             r2,  r2,  #2
   2387        vpaddl.u16      d0,  d0
   2388        bx              r12
   2389 L(ipred_cfl_w16):
   2390        vld1.16         {q2, q3}, [r2]
   2391        vadd.i32        d0,  d0,  d16
   2392        vadd.i16        q2,  q2,  q3
   2393        vadd.i16        d1,  d4,  d5
   2394        vpadd.i16       d1,  d1,  d1
   2395        vpaddl.u16      d1,  d1
   2396        cmp             r4,  #16
   2397        vadd.i32        d0,  d0,  d1
   2398        vshl.u32        d0,  d0,  d17
   2399        beq             1f
   2400        // h = 4/8/32/64
   2401        tst             r4,  #(32+16+8)  // 16 added to make a consecutive bitmask
   2402        movw            lr,  #0x6667
   2403        movw            r8,  #0xAAAB
   2404        it              ne
   2405        movne           lr,  r8
   2406        vdup.32         d18, lr
   2407        vmul.i32        d0,  d0,  d18
   2408        vshr.u32        d0,  d0,  #17
   2409 1:
   2410        vdup.16         q0,  d0[0]
   2411        b               L(ipred_cfl_splat_w16)
   2412 
   2413 L(ipred_cfl_h32):
   2414        vld1.16         {q2, q3},   [r2, :128]!
   2415        vld1.16         {q10, q11}, [r2, :128]!
   2416        vadd.i16        q2,  q2,  q3
   2417        vadd.i16        q10, q10, q11
   2418        vadd.i16        q0,  q2,  q10
   2419        vadd.i16        d0,  d0,  d1
   2420        vpadd.i16       d0,  d0,  d0
   2421        add             r2,  r2,  #2
   2422        vpaddl.u16      d0,  d0
   2423        bx              r12
   2424 L(ipred_cfl_w32):
   2425        vld1.16         {q2, q3},   [r2]!
   2426        vadd.i32        d0,  d0,  d16
   2427        vld1.16         {q10, q11}, [r2]!
   2428        vadd.i16        q2,  q2,  q3
   2429        vadd.i16        q10, q10, q11
   2430        vadd.i16        q2,  q2,  q10
   2431        vadd.i16        d1,  d4,  d5
   2432        vpadd.i16       d1,  d1,  d1
   2433        vpaddl.u16      d1,  d1
   2434        cmp             r4,  #32
   2435        vadd.i32        d0,  d0,  d1
   2436        vshl.u32        d0,  d0,  d17
   2437        beq             1f
   2438        // h = 8/16/64
   2439        cmp             r4,  #8
   2440        movw            lr,  #0x6667
   2441        movw            r8,  #0xAAAB
   2442        it              ne
   2443        movne           lr,  r8
   2444        vdup.32         d18, lr
   2445        vmul.i32        d0,  d0,  d18
   2446        vshr.u32        d0,  d0,  #17
   2447 1:
   2448        vdup.16         q0,  d0[0]
   2449        b               L(ipred_cfl_splat_w16)
   2450 endfunc
   2451 
   2452 // void cfl_ac_420_16bpc_neon(int16_t *const ac, const pixel *const ypx,
   2453 //                            const ptrdiff_t stride, const int w_pad,
   2454 //                            const int h_pad, const int cw, const int ch);
   2455 function ipred_cfl_ac_420_16bpc_neon, export=1
   2456        push            {r4-r8,lr}
   2457        ldrd            r4,  r5,  [sp, #24]
   2458        ldr             r6,  [sp, #32]
   2459        clz             r8,  r5
   2460        lsl             r4,  r4,  #2
   2461        adr             r7,  L(ipred_cfl_ac_420_tbl)
   2462        sub             r8,  r8,  #27
   2463        ldr             r8,  [r7, r8, lsl #2]
   2464        vmov.i32        q8,  #0
   2465        vmov.i32        q9,  #0
   2466        vmov.i32        q10, #0
   2467        vmov.i32        q11, #0
   2468        add             r7,  r7,  r8
   2469        sub             r8,  r6,  r4  // height - h_pad
   2470        rbit            lr,  r5       // rbit(width)
   2471        rbit            r12, r6       // rbit(height)
   2472        clz             lr,  lr       // ctz(width)
   2473        clz             r12, r12      // ctz(height)
   2474        add             lr,  lr,  r12 // log2sz
   2475        add             r12, r1,  r2
   2476        vdup.32         d31, lr
   2477        lsl             r2,  r2,  #1
   2478        vneg.s32        d31, d31      // -log2sz
   2479        bx              r7
   2480 
   2481        .align 2
   2482 L(ipred_cfl_ac_420_tbl):
   2483        .word L(ipred_cfl_ac_420_w16) - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB
   2484        .word L(ipred_cfl_ac_420_w8)  - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB
   2485        .word L(ipred_cfl_ac_420_w4)  - L(ipred_cfl_ac_420_tbl) + CONFIG_THUMB
   2486 
   2487 L(ipred_cfl_ac_420_w4):
   2488 1:      // Copy and subsample input
   2489        vld1.16         {q0}, [r1,  :128], r2
   2490        vld1.16         {q1}, [r12, :128], r2
   2491        vld1.16         {q2}, [r1,  :128], r2
   2492        vld1.16         {q3}, [r12, :128], r2
   2493        vadd.i16        q0,  q0,  q1
   2494        vadd.i16        q2,  q2,  q3
   2495        vpadd.i16       d0,  d0,  d1
   2496        vpadd.i16       d1,  d4,  d5
   2497        vshl.i16        q0,  q0,  #1
   2498        subs            r8,  r8,  #2
   2499        vst1.16         {q0}, [r0, :128]!
   2500        vaddw.u16       q8,  q8,  d0
   2501        vaddw.u16       q9,  q9,  d1
   2502        bgt             1b
   2503        cmp             r4,  #0
   2504        vmov            d0,  d1
   2505        vmov            d2,  d1
   2506        vmov            d3,  d1
   2507 L(ipred_cfl_ac_420_w4_hpad):
   2508        beq             3f // This assumes that all callers already did "cmp r4, #0"
   2509 2:      // Vertical padding (h_pad > 0)
   2510        subs            r4,  r4,  #4
   2511        vst1.16         {q0, q1}, [r0, :128]!
   2512        vaddw.u16       q8,  q8,  d0
   2513        vaddw.u16       q9,  q9,  d1
   2514        vaddw.u16       q10, q10, d2
   2515        vaddw.u16       q11, q11, d3
   2516        bgt             2b
   2517 3:
   2518 L(ipred_cfl_ac_420_w4_calc_subtract_dc):
   2519        // Aggregate the sums
   2520        vadd.i32        q8,  q8,  q9
   2521        vadd.i32        q10, q10, q11
   2522        vadd.i32        q0,  q8,  q10
   2523        vadd.i32        d0,  d0,  d1
   2524        vpadd.i32       d0,  d0,  d0  // sum
   2525        sub             r0,  r0,  r6, lsl #3
   2526        vrshl.u32       d16, d0,  d31 // (sum + (1 << (log2sz - 1))) >>= log2sz
   2527        vdup.16         q8,  d16[0]
   2528 6:      // Subtract dc from ac
   2529        vld1.16         {q0, q1}, [r0, :128]
   2530        subs            r6,  r6,  #4
   2531        vsub.i16        q0,  q0,  q8
   2532        vsub.i16        q1,  q1,  q8
   2533        vst1.16         {q0, q1}, [r0, :128]!
   2534        bgt             6b
   2535        pop             {r4-r8, pc}
   2536 
   2537 L(ipred_cfl_ac_420_w8):
   2538        cmp             r3,  #0
   2539        bne             L(ipred_cfl_ac_420_w8_wpad)
   2540 1:      // Copy and subsample input, without padding
   2541        vld1.16         {q0,  q1},  [r1,  :128], r2
   2542        vld1.16         {q2,  q3},  [r12, :128], r2
   2543        vld1.16         {q12, q13}, [r1,  :128], r2
   2544        vadd.i16        q0,  q0,  q2
   2545        vadd.i16        q1,  q1,  q3
   2546        vld1.16         {q2,  q3},  [r12, :128], r2
   2547        vpadd.i16       d0,  d0,  d1
   2548        vpadd.i16       d1,  d2,  d3
   2549        vadd.i16        q12, q12, q2
   2550        vadd.i16        q13, q13, q3
   2551        vpadd.i16       d2,  d24, d25
   2552        vpadd.i16       d3,  d26, d27
   2553        vshl.i16        q0,  q0,  #1
   2554        vshl.i16        q1,  q1,  #1
   2555        subs            r8,  r8,  #2
   2556        vst1.16         {q0, q1}, [r0, :128]!
   2557        vaddw.u16       q8,  q8,  d0
   2558        vaddw.u16       q9,  q9,  d1
   2559        vaddw.u16       q10, q10, d2
   2560        vaddw.u16       q11, q11, d3
   2561        bgt             1b
   2562        cmp             r4,  #0
   2563        vmov            q0,  q1
   2564        b               L(ipred_cfl_ac_420_w8_hpad)
   2565 
   2566 L(ipred_cfl_ac_420_w8_wpad):
   2567 1:      // Copy and subsample input, padding 4
   2568        vld1.16         {q0}, [r1,  :128], r2
   2569        vld1.16         {q1}, [r12, :128], r2
   2570        vld1.16         {q2}, [r1,  :128], r2
   2571        vld1.16         {q3}, [r12, :128], r2
   2572        vadd.i16        q0,  q0,  q1
   2573        vadd.i16        q2,  q2,  q3
   2574        vpadd.i16       d0,  d0,  d1
   2575        vpadd.i16       d1,  d4,  d5
   2576        vshl.i16        q0,  q0,  #1
   2577        vdup.16         d3,  d1[3]
   2578        vmov            d2,  d1
   2579        vdup.16         d1,  d0[3]
   2580        subs            r8,  r8,  #2
   2581        vst1.16         {q0, q1}, [r0, :128]!
   2582        vaddw.u16       q8,  q8,  d0
   2583        vaddw.u16       q9,  q9,  d1
   2584        vaddw.u16       q10, q10, d2
   2585        vaddw.u16       q11, q11, d3
   2586        bgt             1b
   2587        cmp             r4,  #0
   2588        vmov            q0,  q1
   2589 
   2590 L(ipred_cfl_ac_420_w8_hpad):
   2591        beq             3f // This assumes that all callers already did "cmp r4, #0"
   2592 2:      // Vertical padding (h_pad > 0)
   2593        subs            r4,  r4,  #4
   2594        vst1.16         {q0, q1}, [r0, :128]!
   2595        vaddw.u16       q8,  q8,  d0
   2596        vaddw.u16       q9,  q9,  d1
   2597        vaddw.u16       q10, q10, d2
   2598        vaddw.u16       q11, q11, d3
   2599        vst1.16         {q0, q1}, [r0, :128]!
   2600        vaddw.u16       q8,  q8,  d0
   2601        vaddw.u16       q9,  q9,  d1
   2602        vaddw.u16       q10, q10, d2
   2603        vaddw.u16       q11, q11, d3
   2604        bgt             2b
   2605 3:
   2606 
   2607        // Double the height and reuse the w4 summing/subtracting
   2608        lsl             r6,  r6,  #1
   2609        b               L(ipred_cfl_ac_420_w4_calc_subtract_dc)
   2610 
   2611 L(ipred_cfl_ac_420_w16):
   2612        adr             r7,  L(ipred_cfl_ac_420_w16_tbl)
   2613        ldr             r3,  [r7, r3, lsl #2]
   2614        add             r7,  r7,  r3
   2615        bx              r7
   2616 
   2617        .align 2
   2618 L(ipred_cfl_ac_420_w16_tbl):
   2619        .word L(ipred_cfl_ac_420_w16_wpad0) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB
   2620        .word L(ipred_cfl_ac_420_w16_wpad1) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB
   2621        .word L(ipred_cfl_ac_420_w16_wpad2) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB
   2622        .word L(ipred_cfl_ac_420_w16_wpad3) - L(ipred_cfl_ac_420_w16_tbl) + CONFIG_THUMB
   2623 
   2624 L(ipred_cfl_ac_420_w16_wpad0):
   2625        sub             r2,  r2,  #32
   2626 1:      // Copy and subsample input, without padding
   2627        vld1.16         {q0,  q1},  [r1,  :128]!
   2628        vld1.16         {q12, q13}, [r12, :128]!
   2629        vld1.16         {q2,  q3},  [r1,  :128], r2
   2630        vadd.i16        q0,  q0,  q12
   2631        vadd.i16        q1,  q1,  q13
   2632        vld1.16         {q12, q13}, [r12, :128], r2
   2633        vpadd.i16       d0,  d0,  d1
   2634        vpadd.i16       d1,  d2,  d3
   2635        vadd.i16        q2,  q2,  q12
   2636        vadd.i16        q3,  q3,  q13
   2637        vpadd.i16       d2,  d4,  d5
   2638        vpadd.i16       d3,  d6,  d7
   2639        vshl.i16        q0,  q0,  #1
   2640        vshl.i16        q1,  q1,  #1
   2641        subs            r8,  r8,  #1
   2642        vst1.16         {q0, q1}, [r0, :128]!
   2643        vaddw.u16       q8,  q8,  d0
   2644        vaddw.u16       q9,  q9,  d1
   2645        vaddw.u16       q10, q10, d2
   2646        vaddw.u16       q11, q11, d3
   2647        bgt             1b
   2648        cmp             r4,  #0
   2649        b               L(ipred_cfl_ac_420_w16_hpad)
   2650 
   2651 L(ipred_cfl_ac_420_w16_wpad1):
   2652        sub             r2,  r2,  #32
   2653 1:      // Copy and subsample input, padding 4
   2654        vld1.16         {q0,  q1},  [r1,  :128]!
   2655        vld1.16         {q12, q13}, [r12, :128]!
   2656        vld1.16         {q2},       [r1,  :128], r2
   2657        vadd.i16        q0,  q0,  q12
   2658        vadd.i16        q1,  q1,  q13
   2659        vld1.16         {q12},     [r12, :128], r2
   2660        vpadd.i16       d0,  d0,  d1
   2661        vadd.i16        q2,  q2,  q12
   2662        vpadd.i16       d1,  d2,  d3
   2663        vpadd.i16       d2,  d4,  d5
   2664        vshl.i16        q0,  q0,  #1
   2665        vshl.i16        d2,  d2,  #1
   2666        subs            r8,  r8,  #1
   2667        vdup.16         d3,  d2[3]
   2668        vst1.16         {q0, q1}, [r0, :128]!
   2669        vaddw.u16       q8,  q8,  d0
   2670        vaddw.u16       q9,  q9,  d1
   2671        vaddw.u16       q10, q10, d2
   2672        vaddw.u16       q11, q11, d3
   2673        bgt             1b
   2674        cmp             r4,  #0
   2675        b               L(ipred_cfl_ac_420_w16_hpad)
   2676 
   2677 L(ipred_cfl_ac_420_w16_wpad2):
   2678 1:      // Copy and subsample input, padding 8
   2679        vld1.16         {q0,  q1},  [r1,  :128], r2
   2680        vld1.16         {q12, q13}, [r12, :128], r2
   2681        vadd.i16        q0,  q0,  q12
   2682        vadd.i16        q1,  q1,  q13
   2683        vpadd.i16       d0,  d0,  d1
   2684        vpadd.i16       d1,  d2,  d3
   2685        vshl.i16        q0,  q0,  #1
   2686        subs            r8,  r8,  #1
   2687        vdup.16         q1,  d1[3]
   2688        vst1.16         {q0, q1}, [r0, :128]!
   2689        vaddw.u16       q8,  q8,  d0
   2690        vaddw.u16       q9,  q9,  d1
   2691        vaddw.u16       q10, q10, d2
   2692        vaddw.u16       q11, q11, d3
   2693        bgt             1b
   2694        cmp             r4,  #0
   2695        b               L(ipred_cfl_ac_420_w16_hpad)
   2696 
   2697 L(ipred_cfl_ac_420_w16_wpad3):
   2698 1:      // Copy and subsample input, padding 12
   2699        vld1.16         {q0},  [r1,  :128], r2
   2700        vld1.16         {q12}, [r12, :128], r2
   2701        vadd.i16        q0,  q0,  q12
   2702        vpadd.i16       d0,  d0,  d1
   2703        vshl.i16        d0,  d0,  #1
   2704        subs            r8,  r8,  #1
   2705        vdup.16         q1,  d0[3]
   2706        vdup.16         d1,  d0[3]
   2707        vst1.16         {q0, q1}, [r0, :128]!
   2708        vaddw.u16       q8,  q8,  d0
   2709        vaddw.u16       q9,  q9,  d1
   2710        vaddw.u16       q10, q10, d2
   2711        vaddw.u16       q11, q11, d3
   2712        bgt             1b
   2713        cmp             r4,  #0
   2714        b               L(ipred_cfl_ac_420_w16_hpad)
   2715 
   2716 L(ipred_cfl_ac_420_w16_hpad):
   2717        beq             3f // This assumes that all callers already did "cmp r4, #0"
   2718 2:      // Vertical padding (h_pad > 0)
   2719        subs            r4,  r4,  #2
   2720        vst1.16         {q0, q1}, [r0, :128]!
   2721        vaddw.u16       q8,  q8,  d0
   2722        vaddw.u16       q9,  q9,  d1
   2723        vaddw.u16       q10, q10, d2
   2724        vaddw.u16       q11, q11, d3
   2725        vst1.16         {q0, q1}, [r0, :128]!
   2726        vaddw.u16       q8,  q8,  d0
   2727        vaddw.u16       q9,  q9,  d1
   2728        vaddw.u16       q10, q10, d2
   2729        vaddw.u16       q11, q11, d3
   2730        bgt             2b
   2731 3:
   2732 
   2733        // Quadruple the height and reuse the w4 summing/subtracting
   2734        lsl             r6,  r6,  #2
   2735        b               L(ipred_cfl_ac_420_w4_calc_subtract_dc)
   2736 endfunc
   2737 
   2738 // void cfl_ac_422_16bpc_neon(int16_t *const ac, const pixel *const ypx,
   2739 //                            const ptrdiff_t stride, const int w_pad,
   2740 //                            const int h_pad, const int cw, const int ch);
   2741 function ipred_cfl_ac_422_16bpc_neon, export=1
   2742        push            {r4-r8,lr}
   2743        ldrd            r4,  r5,  [sp, #24]
   2744        ldr             r6,  [sp, #32]
   2745        clz             r8,  r5
   2746        lsl             r4,  r4,  #2
   2747        adr             r7,  L(ipred_cfl_ac_422_tbl)
   2748        sub             r8,  r8,  #27
   2749        ldr             r8,  [r7, r8, lsl #2]
   2750        vmov.i16        q8,  #0
   2751        vmov.i16        q9,  #0
   2752        vmov.i16        q10, #0
   2753        vmov.i16        q11, #0
   2754        add             r7,  r7,  r8
   2755        sub             r8,  r6,  r4  // height - h_pad
   2756        rbit            lr,  r5       // rbit(width)
   2757        rbit            r12, r6       // rbit(height)
   2758        clz             lr,  lr       // ctz(width)
   2759        clz             r12, r12      // ctz(height)
   2760        add             lr,  lr,  r12 // log2sz
   2761        add             r12, r1,  r2
   2762        vdup.32         d31, lr
   2763        lsl             r2,  r2,  #1
   2764        vneg.s32        d31, d31      // -log2sz
   2765        bx              r7
   2766 
   2767        .align 2
   2768 L(ipred_cfl_ac_422_tbl):
   2769        .word L(ipred_cfl_ac_422_w16) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB
   2770        .word L(ipred_cfl_ac_422_w8) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB
   2771        .word L(ipred_cfl_ac_422_w4) - L(ipred_cfl_ac_422_tbl) + CONFIG_THUMB
   2772 
   2773 L(ipred_cfl_ac_422_w4):
   2774 1:      // Copy and subsample input
   2775        vld1.16         {q0}, [r1,  :128], r2
   2776        vld1.16         {q1}, [r12, :128], r2
   2777        vld1.16         {q2}, [r1,  :128], r2
   2778        vld1.16         {q3}, [r12, :128], r2
   2779        vpadd.i16       d0,  d0,  d1
   2780        vpadd.i16       d1,  d2,  d3
   2781        vpadd.i16       d2,  d4,  d5
   2782        vpadd.i16       d3,  d6,  d7
   2783        vshl.i16        q0,  q0,  #2
   2784        vshl.i16        q1,  q1,  #2
   2785        subs            r8,  r8,  #4
   2786        vst1.16         {q0, q1}, [r0, :128]!
   2787        vaddw.u16       q8,  q8,  d0
   2788        vaddw.u16       q9,  q9,  d1
   2789        vaddw.u16       q10, q10, d2
   2790        vaddw.u16       q11, q11, d3
   2791        bgt             1b
   2792        cmp             r4,  #0
   2793        vmov            d0,  d3
   2794        vmov            d1,  d3
   2795        vmov            d2,  d3
   2796        b               L(ipred_cfl_ac_420_w4_hpad)
   2797 
   2798 L(ipred_cfl_ac_422_w8):
   2799        cmp             r3,  #0
   2800        bne             L(ipred_cfl_ac_422_w8_wpad)
   2801 1:      // Copy and subsample input, without padding
   2802        vld1.16         {q0,  q1},  [r1,  :128], r2
   2803        vld1.16         {q2,  q3},  [r12, :128], r2
   2804        vld1.16         {q12, q13}, [r1,  :128], r2
   2805        vpadd.i16       d0,  d0,  d1
   2806        vpadd.i16       d1,  d2,  d3
   2807        vpadd.i16       d2,  d4,  d5
   2808        vpadd.i16       d3,  d6,  d7
   2809        vld1.16         {q2, q3}, [r12, :128], r2
   2810        vpadd.i16       d24, d24, d25
   2811        vpadd.i16       d25, d26, d27
   2812        vpadd.i16       d26, d4,  d5
   2813        vpadd.i16       d27, d6,  d7
   2814        vshl.i16        q0,  q0,  #2
   2815        vshl.i16        q1,  q1,  #2
   2816        vshl.i16        q2,  q12, #2
   2817        vshl.i16        q3,  q13, #2
   2818        subs            r8,  r8,  #4
   2819        vst1.16         {q0, q1}, [r0, :128]!
   2820        vaddw.u16       q8,  q8,  d0
   2821        vaddw.u16       q9,  q9,  d1
   2822        vaddw.u16       q10, q10, d2
   2823        vaddw.u16       q11, q11, d3
   2824        vst1.16         {q2, q3}, [r0, :128]!
   2825        vaddw.u16       q8,  q8,  d4
   2826        vaddw.u16       q9,  q9,  d5
   2827        vaddw.u16       q10, q10, d6
   2828        vaddw.u16       q11, q11, d7
   2829        bgt             1b
   2830        cmp             r4,  #0
   2831        vmov            q0,  q3
   2832        vmov            q1,  q3
   2833        b               L(ipred_cfl_ac_420_w8_hpad)
   2834 
   2835 L(ipred_cfl_ac_422_w8_wpad):
   2836 1:      // Copy and subsample input, padding 4
   2837        vld1.16         {q0},  [r1,  :128], r2
   2838        vld1.16         {q2},  [r12, :128], r2
   2839        vld1.16         {q12}, [r1,  :128], r2
   2840        vpadd.i16       d0,  d0,  d1
   2841        vpadd.i16       d1,  d4,  d5
   2842        vld1.16         {q2, q3}, [r12, :128], r2
   2843        vpadd.i16       d24, d24, d25
   2844        vpadd.i16       d25, d4,  d5
   2845        vshl.i16        q0,  q0,  #2
   2846        vshl.i16        q12, q12, #2
   2847        vdup.16         d7,  d25[3]
   2848        vmov            d6,  d25
   2849        vdup.16         d5,  d24[3]
   2850        vmov            d4,  d24
   2851        vdup.16         d3,  d1[3]
   2852        vmov            d2,  d1
   2853        vdup.16         d1,  d0[3]
   2854        subs            r8,  r8,  #4
   2855        vst1.16         {q0, q1}, [r0, :128]!
   2856        vaddw.u16       q8,  q8,  d0
   2857        vaddw.u16       q9,  q9,  d1
   2858        vaddw.u16       q10, q10, d2
   2859        vaddw.u16       q11, q11, d3
   2860        vst1.16         {q2, q3}, [r0, :128]!
   2861        vaddw.u16       q8,  q8,  d4
   2862        vaddw.u16       q9,  q9,  d5
   2863        vaddw.u16       q10, q10, d6
   2864        vaddw.u16       q11, q11, d7
   2865        bgt             1b
   2866        cmp             r4,  #0
   2867        vmov            q0,  q3
   2868        vmov            q1,  q3
   2869        b               L(ipred_cfl_ac_420_w8_hpad)
   2870 
   2871 L(ipred_cfl_ac_422_w16):
   2872        adr             r7,  L(ipred_cfl_ac_422_w16_tbl)
   2873        ldr             r3,  [r7, r3, lsl #2]
   2874        add             r7,  r7,  r3
   2875        bx              r7
   2876 
   2877        .align 2
   2878 L(ipred_cfl_ac_422_w16_tbl):
   2879        .word L(ipred_cfl_ac_422_w16_wpad0) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB
   2880        .word L(ipred_cfl_ac_422_w16_wpad1) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB
   2881        .word L(ipred_cfl_ac_422_w16_wpad2) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB
   2882        .word L(ipred_cfl_ac_422_w16_wpad3) - L(ipred_cfl_ac_422_w16_tbl) + CONFIG_THUMB
   2883 
   2884 L(ipred_cfl_ac_422_w16_wpad0):
   2885        sub             r2,  r2,  #32
   2886 1:      // Copy and subsample input, without padding
   2887        vld1.16         {q0,  q1},  [r1,  :128]!
   2888        vld1.16         {q2,  q3},  [r12, :128]!
   2889        vld1.16         {q12, q13}, [r1,  :128], r2
   2890        vpadd.i16       d0,  d0,  d1
   2891        vpadd.i16       d1,  d2,  d3
   2892        vpadd.i16       d2,  d24, d25
   2893        vpadd.i16       d3,  d26, d27
   2894        vld1.16         {q12, q13}, [r12, :128], r2
   2895        vpadd.i16       d4,  d4,  d5
   2896        vpadd.i16       d5,  d6,  d7
   2897        vpadd.i16       d6,  d24, d25
   2898        vpadd.i16       d7,  d26, d27
   2899        vshl.i16        q0,  q0,  #2
   2900        vshl.i16        q1,  q1,  #2
   2901        vshl.i16        q2,  q2,  #2
   2902        vshl.i16        q3,  q3,  #2
   2903        subs            r8,  r8,  #2
   2904        vst1.16         {q0, q1}, [r0, :128]!
   2905        vaddw.u16       q8,  q8,  d0
   2906        vaddw.u16       q9,  q9,  d1
   2907        vaddw.u16       q10, q10, d2
   2908        vaddw.u16       q11, q11, d3
   2909        vst1.16         {q2, q3}, [r0, :128]!
   2910        vaddw.u16       q8,  q8,  d4
   2911        vaddw.u16       q9,  q9,  d5
   2912        vaddw.u16       q10, q10, d6
   2913        vaddw.u16       q11, q11, d7
   2914        bgt             1b
   2915        cmp             r4,  #0
   2916        vmov            q0,  q2
   2917        vmov            q1,  q3
   2918        b               L(ipred_cfl_ac_420_w16_hpad)
   2919 
   2920 L(ipred_cfl_ac_422_w16_wpad1):
   2921        sub             r2,  r2,  #32
   2922 1:      // Copy and subsample input, padding 4
   2923        vld1.16         {q0,  q1},  [r1,  :128]!
   2924        vld1.16         {q2,  q3},  [r12, :128]!
   2925        vld1.16         {q12},      [r1,  :128], r2
   2926        vpadd.i16       d0,  d0,  d1
   2927        vpadd.i16       d1,  d2,  d3
   2928        vpadd.i16       d2,  d24, d25
   2929        vld1.16         {q12},      [r12, :128], r2
   2930        vpadd.i16       d4,  d4,  d5
   2931        vpadd.i16       d5,  d6,  d7
   2932        vpadd.i16       d6,  d24, d25
   2933        vshl.i16        q0,  q0,  #2
   2934        vshl.i16        d2,  d2,  #2
   2935        vshl.i16        q2,  q2,  #2
   2936        vshl.i16        d6,  d6,  #2
   2937        vdup.16         d3,  d2[3]
   2938        vdup.16         d7,  d6[3]
   2939        subs            r8,  r8,  #2
   2940        vst1.16         {q0, q1}, [r0, :128]!
   2941        vaddw.u16       q8,  q8,  d0
   2942        vaddw.u16       q9,  q9,  d1
   2943        vaddw.u16       q10, q10, d2
   2944        vaddw.u16       q11, q11, d3
   2945        vst1.16         {q2, q3}, [r0, :128]!
   2946        vaddw.u16       q8,  q8,  d4
   2947        vaddw.u16       q9,  q9,  d5
   2948        vaddw.u16       q10, q10, d6
   2949        vaddw.u16       q11, q11, d7
   2950        bgt             1b
   2951        cmp             r4,  #0
   2952        vmov            q0,  q2
   2953        vmov            q1,  q3
   2954        b               L(ipred_cfl_ac_420_w16_hpad)
   2955 
   2956 L(ipred_cfl_ac_422_w16_wpad2):
   2957 1:      // Copy and subsample input, padding 8
   2958        vld1.16         {q0,  q1},  [r1,  :128], r2
   2959        vld1.16         {q2,  q3},  [r12, :128], r2
   2960        vpadd.i16       d0,  d0,  d1
   2961        vpadd.i16       d1,  d2,  d3
   2962        vpadd.i16       d4,  d4,  d5
   2963        vpadd.i16       d5,  d6,  d7
   2964        vshl.i16        q0,  q0,  #2
   2965        vshl.i16        q2,  q2,  #2
   2966        vdup.16         q1,  d1[3]
   2967        vdup.16         q3,  d5[3]
   2968        subs            r8,  r8,  #2
   2969        vst1.16         {q0, q1}, [r0, :128]!
   2970        vaddw.u16       q8,  q8,  d0
   2971        vaddw.u16       q9,  q9,  d1
   2972        vaddw.u16       q10, q10, d2
   2973        vaddw.u16       q11, q11, d3
   2974        vst1.16         {q2, q3}, [r0, :128]!
   2975        vaddw.u16       q8,  q8,  d4
   2976        vaddw.u16       q9,  q9,  d5
   2977        vaddw.u16       q10, q10, d6
   2978        vaddw.u16       q11, q11, d7
   2979        bgt             1b
   2980        cmp             r4,  #0
   2981        vmov            q0,  q2
   2982        vmov            q1,  q3
   2983        b               L(ipred_cfl_ac_420_w16_hpad)
   2984 
   2985 L(ipred_cfl_ac_422_w16_wpad3):
   2986 1:      // Copy and subsample input, padding 12
   2987        vld1.16         {q0}, [r1,  :128], r2
   2988        vld1.16         {q2}, [r12, :128], r2
   2989        vpadd.i16       d0,  d0,  d1
   2990        vpadd.i16       d1,  d4,  d5
   2991        vshl.i16        q0,  q0,  #2
   2992        vdup.16         q3,  d1[3]
   2993        vdup.16         q1,  d0[3]
   2994        vdup.16         d5,  d1[3]
   2995        vmov            d4,  d1
   2996        vdup.16         d1,  d0[3]
   2997        subs            r8,  r8,  #2
   2998        vst1.16         {q0, q1}, [r0, :128]!
   2999        vaddw.u16       q8,  q8,  d0
   3000        vaddw.u16       q9,  q9,  d1
   3001        vaddw.u16       q10, q10, d2
   3002        vaddw.u16       q11, q11, d3
   3003        vst1.16         {q2, q3}, [r0, :128]!
   3004        vaddw.u16       q8,  q8,  d4
   3005        vaddw.u16       q9,  q9,  d5
   3006        vaddw.u16       q10, q10, d6
   3007        vaddw.u16       q11, q11, d7
   3008        bgt             1b
   3009        cmp             r4,  #0
   3010        vmov            q0,  q2
   3011        vmov            q1,  q3
   3012        b               L(ipred_cfl_ac_420_w16_hpad)
   3013 endfunc
   3014 
   3015 // void cfl_ac_444_16bpc_neon(int16_t *const ac, const pixel *const ypx,
   3016 //                            const ptrdiff_t stride, const int w_pad,
   3017 //                            const int h_pad, const int cw, const int ch);
   3018 function ipred_cfl_ac_444_16bpc_neon, export=1
   3019        push            {r4-r8,lr}
   3020        ldrd            r4,  r5,  [sp, #24]
   3021        ldr             r6,  [sp, #32]
   3022        clz             r8,  r5
   3023        lsl             r4,  r4,  #2
   3024        adr             r7,  L(ipred_cfl_ac_444_tbl)
   3025        sub             r8,  r8,  #26
   3026        ldr             r8,  [r7, r8, lsl #2]
   3027        vmov.i16        q8,  #0
   3028        vmov.i16        q9,  #0
   3029        vmov.i16        q10, #0
   3030        vmov.i16        q11, #0
   3031        add             r7,  r7,  r8
   3032        sub             r8,  r6,  r4  // height - h_pad
   3033        rbit            lr,  r5       // rbit(width)
   3034        rbit            r12, r6       // rbit(height)
   3035        clz             lr,  lr       // ctz(width)
   3036        clz             r12, r12      // ctz(height)
   3037        add             lr,  lr,  r12 // log2sz
   3038        add             r12, r1,  r2
   3039        vdup.32         d31, lr
   3040        lsl             r2,  r2,  #1
   3041        vneg.s32        d31, d31      // -log2sz
   3042        bx              r7
   3043 
   3044        .align 2
   3045 L(ipred_cfl_ac_444_tbl):
   3046        .word L(ipred_cfl_ac_444_w32) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB
   3047        .word L(ipred_cfl_ac_444_w16) - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB
   3048        .word L(ipred_cfl_ac_444_w8)  - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB
   3049        .word L(ipred_cfl_ac_444_w4)  - L(ipred_cfl_ac_444_tbl) + CONFIG_THUMB
   3050 
   3051 L(ipred_cfl_ac_444_w4):
   3052 1:      // Copy and expand input
   3053        vld1.16         {d0}, [r1,  :64], r2
   3054        vld1.16         {d1}, [r12, :64], r2
   3055        vld1.16         {d2}, [r1,  :64], r2
   3056        vld1.16         {d3}, [r12, :64], r2
   3057        vshl.i16        q0,  q0,  #3
   3058        vshl.i16        q1,  q1,  #3
   3059        subs            r8,  r8,  #4
   3060        vst1.16         {q0, q1}, [r0, :128]!
   3061        vaddw.u16       q8,  q8,  d0
   3062        vaddw.u16       q9,  q9,  d1
   3063        vaddw.u16       q10, q10, d2
   3064        vaddw.u16       q11, q11, d3
   3065        bgt             1b
   3066        cmp             r4,  #0
   3067        vmov            d0,  d3
   3068        vmov            d1,  d3
   3069        vmov            d2,  d3
   3070        b               L(ipred_cfl_ac_420_w4_hpad)
   3071 
   3072 L(ipred_cfl_ac_444_w8):
   3073 1:      // Copy and expand input
   3074        vld1.16         {q0}, [r1,  :128], r2
   3075        vld1.16         {q1}, [r12, :128], r2
   3076        vld1.16         {q2}, [r1,  :128], r2
   3077        vld1.16         {q3}, [r12, :128], r2
   3078        vshl.i16        q0,  q0,  #3
   3079        vshl.i16        q1,  q1,  #3
   3080        vshl.i16        q2,  q2,  #3
   3081        vshl.i16        q3,  q3,  #3
   3082        subs            r8,  r8,  #4
   3083        vst1.16         {q0, q1}, [r0, :128]!
   3084        vaddw.u16       q8,  q8,  d0
   3085        vaddw.u16       q9,  q9,  d1
   3086        vaddw.u16       q10, q10, d2
   3087        vaddw.u16       q11, q11, d3
   3088        vst1.16         {q2, q3}, [r0, :128]!
   3089        vaddw.u16       q8,  q8,  d4
   3090        vaddw.u16       q9,  q9,  d5
   3091        vaddw.u16       q10, q10, d6
   3092        vaddw.u16       q11, q11, d7
   3093        bgt             1b
   3094        cmp             r4,  #0
   3095        vmov            q0,  q3
   3096        vmov            q1,  q3
   3097        b               L(ipred_cfl_ac_420_w8_hpad)
   3098 
   3099 L(ipred_cfl_ac_444_w16):
   3100        cmp             r3,  #0
   3101        bne             L(ipred_cfl_ac_444_w16_wpad)
   3102 1:      // Copy and expand input, without padding
   3103        vld1.16         {q0, q1}, [r1,  :128], r2
   3104        vld1.16         {q2, q3}, [r12, :128], r2
   3105        vshl.i16        q0,  q0,  #3
   3106        vshl.i16        q1,  q1,  #3
   3107        vshl.i16        q2,  q2,  #3
   3108        vshl.i16        q3,  q3,  #3
   3109        subs            r8,  r8,  #2
   3110        vst1.16         {q0, q1}, [r0, :128]!
   3111        vaddw.u16       q8,  q8,  d0
   3112        vaddw.u16       q9,  q9,  d1
   3113        vaddw.u16       q10, q10, d2
   3114        vaddw.u16       q11, q11, d3
   3115        vst1.16         {q2, q3}, [r0, :128]!
   3116        vaddw.u16       q8,  q8,  d4
   3117        vaddw.u16       q9,  q9,  d5
   3118        vaddw.u16       q10, q10, d6
   3119        vaddw.u16       q11, q11, d7
   3120        bgt             1b
   3121        cmp             r4,  #0
   3122        vmov            q0,  q2
   3123        vmov            q1,  q3
   3124        b               L(ipred_cfl_ac_420_w16_hpad)
   3125 
   3126 L(ipred_cfl_ac_444_w16_wpad):
   3127 1:      // Copy and expand input, padding 8
   3128        vld1.16         {q0}, [r1,  :128], r2
   3129        vld1.16         {q2}, [r12, :128], r2
   3130        vshl.i16        q0,  q0,  #3
   3131        vshl.i16        q2,  q2,  #3
   3132        vdup.16         q1,  d1[3]
   3133        vdup.16         q3,  d5[3]
   3134        subs            r8,  r8,  #2
   3135        vst1.16         {q0, q1}, [r0, :128]!
   3136        vaddw.u16       q8,  q8,  d0
   3137        vaddw.u16       q9,  q9,  d1
   3138        vaddw.u16       q10, q10, d2
   3139        vaddw.u16       q11, q11, d3
   3140        vst1.16         {q2, q3}, [r0, :128]!
   3141        vaddw.u16       q8,  q8,  d4
   3142        vaddw.u16       q9,  q9,  d5
   3143        vaddw.u16       q10, q10, d6
   3144        vaddw.u16       q11, q11, d7
   3145        bgt             1b
   3146        cmp             r4,  #0
   3147        vmov            q0,  q2
   3148        vmov            q1,  q3
   3149        b               L(ipred_cfl_ac_420_w16_hpad)
   3150 
   3151 L(ipred_cfl_ac_444_w32):
   3152        adr             r7,  L(ipred_cfl_ac_444_w32_tbl)
   3153        ldr             r3,  [r7, r3, lsl #1] // (w3>>1) << 2
   3154        asr             r2,  r2,  #1
   3155        add             r7,  r7,  r3
   3156        bx              r7
   3157 
   3158        .align 2
   3159 L(ipred_cfl_ac_444_w32_tbl):
   3160        .word L(ipred_cfl_ac_444_w32_wpad0) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB
   3161        .word L(ipred_cfl_ac_444_w32_wpad2) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB
   3162        .word L(ipred_cfl_ac_444_w32_wpad4) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB
   3163        .word L(ipred_cfl_ac_444_w32_wpad6) - L(ipred_cfl_ac_444_w32_tbl) + CONFIG_THUMB
   3164 
   3165 L(ipred_cfl_ac_444_w32_wpad0):
   3166        sub             r2,  r2,  #32
   3167 1:      // Copy and expand input, without padding
   3168        vld1.16         {q0, q1}, [r1, :128]!
   3169        vld1.16         {q2, q3}, [r1, :128], r2
   3170        vshl.i16        q0,  q0,  #3
   3171        vshl.i16        q1,  q1,  #3
   3172        vshl.i16        q2,  q2,  #3
   3173        vshl.i16        q3,  q3,  #3
   3174        subs            r8,  r8,  #1
   3175        vst1.16         {q0, q1}, [r0, :128]!
   3176        vaddw.u16       q8,  q8,  d0
   3177        vaddw.u16       q9,  q9,  d1
   3178        vaddw.u16       q10, q10, d2
   3179        vaddw.u16       q11, q11, d3
   3180        vst1.16         {q2, q3}, [r0, :128]!
   3181        vaddw.u16       q8,  q8,  d4
   3182        vaddw.u16       q9,  q9,  d5
   3183        vaddw.u16       q10, q10, d6
   3184        vaddw.u16       q11, q11, d7
   3185        bgt             1b
   3186        cmp             r4,  #0
   3187        b               L(ipred_cfl_ac_444_w32_hpad)
   3188 
   3189 L(ipred_cfl_ac_444_w32_wpad2):
   3190        sub             r2,  r2,  #32
   3191 1:      // Copy and expand input, padding 8
   3192        vld1.16         {q0, q1}, [r1, :128]!
   3193        vld1.16         {q2},     [r1, :128], r2
   3194        vshl.i16        q0,  q0,  #3
   3195        vshl.i16        q1,  q1,  #3
   3196        vshl.i16        q2,  q2,  #3
   3197        subs            r8,  r8,  #1
   3198        vst1.16         {q0, q1}, [r0, :128]!
   3199        vdup.16         q3,  d5[3]
   3200        vaddw.u16       q8,  q8,  d0
   3201        vaddw.u16       q9,  q9,  d1
   3202        vaddw.u16       q10, q10, d2
   3203        vaddw.u16       q11, q11, d3
   3204        vst1.16         {q2, q3}, [r0, :128]!
   3205        vaddw.u16       q8,  q8,  d4
   3206        vaddw.u16       q9,  q9,  d5
   3207        vaddw.u16       q10, q10, d6
   3208        vaddw.u16       q11, q11, d7
   3209        bgt             1b
   3210        cmp             r4,  #0
   3211        b               L(ipred_cfl_ac_444_w32_hpad)
   3212 
   3213 L(ipred_cfl_ac_444_w32_wpad4):
   3214 1:      // Copy and expand input, padding 16
   3215        vld1.16         {q0, q1}, [r1, :128], r2
   3216        vshl.i16        q0,  q0,  #3
   3217        vshl.i16        q1,  q1,  #3
   3218        subs            r8,  r8,  #1
   3219        vst1.16         {q0, q1}, [r0, :128]!
   3220        vdup.16         q2,  d3[3]
   3221        vdup.16         q3,  d3[3]
   3222        vaddw.u16       q8,  q8,  d0
   3223        vaddw.u16       q9,  q9,  d1
   3224        vaddw.u16       q10, q10, d2
   3225        vaddw.u16       q11, q11, d3
   3226        vst1.16         {q2, q3}, [r0, :128]!
   3227        vaddw.u16       q8,  q8,  d4
   3228        vaddw.u16       q9,  q9,  d5
   3229        vaddw.u16       q10, q10, d6
   3230        vaddw.u16       q11, q11, d7
   3231        bgt             1b
   3232        cmp             r4,  #0
   3233        b               L(ipred_cfl_ac_444_w32_hpad)
   3234 
   3235 L(ipred_cfl_ac_444_w32_wpad6):
   3236 1:      // Copy and expand input, padding 24
   3237        vld1.16         {q0}, [r1, :128], r2
   3238        vshl.i16        q0,  q0,  #3
   3239        subs            r8,  r8,  #1
   3240        vdup.16         q1,  d1[3]
   3241        vst1.16         {q0, q1}, [r0, :128]!
   3242        vdup.16         q2,  d1[3]
   3243        vdup.16         q3,  d1[3]
   3244        vaddw.u16       q8,  q8,  d0
   3245        vaddw.u16       q9,  q9,  d1
   3246        vaddw.u16       q10, q10, d2
   3247        vaddw.u16       q11, q11, d3
   3248        vst1.16         {q2, q3}, [r0, :128]!
   3249        vaddw.u16       q8,  q8,  d4
   3250        vaddw.u16       q9,  q9,  d5
   3251        vaddw.u16       q10, q10, d6
   3252        vaddw.u16       q11, q11, d7
   3253        bgt             1b
   3254        cmp             r4,  #0
   3255 
   3256 L(ipred_cfl_ac_444_w32_hpad):
   3257        beq             3f // This assumes that all callers already did "cmp r4, #0"
   3258 2:      // Vertical padding (h_pad > 0)
   3259        subs            r4,  r4,  #1
   3260        vst1.16         {q0, q1}, [r0, :128]!
   3261        vaddw.u16       q8,  q8,  d0
   3262        vaddw.u16       q9,  q9,  d1
   3263        vaddw.u16       q10, q10, d2
   3264        vaddw.u16       q11, q11, d3
   3265        vst1.16         {q2, q3}, [r0, :128]!
   3266        vaddw.u16       q8,  q8,  d4
   3267        vaddw.u16       q9,  q9,  d5
   3268        vaddw.u16       q10, q10, d6
   3269        vaddw.u16       q11, q11, d7
   3270        bgt             2b
   3271 3:
   3272 
   3273        //  Multiply the height by eight and reuse the w4 subtracting
   3274        lsl             r6,  r6,  #3
   3275        b               L(ipred_cfl_ac_420_w4_calc_subtract_dc)
   3276 endfunc