Home | History | Annotate | Download | only in arm
      1 @ This file was created from a .asm file
      2 @  using the ads2gas.pl script.
      3 	.equ DO1STROUNDING, 0
      4 	.syntax unified
      5 @
      6 @  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
      7 @
      8 @  Use of this source code is governed by a BSD-style license
      9 @  that can be found in the LICENSE file in the root of the source
     10 @  tree. An additional intellectual property rights grant can be found
     11 @  in the file PATENTS.  All contributing project authors may
     12 @  be found in the AUTHORS file in the root of the source tree.
     13 @
     14 
     15     .global vpx_lpf_horizontal_16_neon
     16 	.type vpx_lpf_horizontal_16_neon, function
     17     .global vpx_lpf_horizontal_16_dual_neon
     18 	.type vpx_lpf_horizontal_16_dual_neon, function
     19     .global vpx_lpf_vertical_16_neon
     20 	.type vpx_lpf_vertical_16_neon, function
     21     .global vpx_lpf_vertical_16_dual_neon
     22 	.type vpx_lpf_vertical_16_dual_neon, function
     23    .arm
     24 
     25 .text
     26 .p2align 2
     27 
     28 @ void mb_lpf_horizontal_edge(uint8_t *s, int p,
     29 @                             const uint8_t *blimit,
     30 @                             const uint8_t *limit,
     31 @                             const uint8_t *thresh,
     32 @                             int count)
     33 @ r0    uint8_t *s,
     34 @ r1    int p, /* pitch */
     35 @ r2    const uint8_t *blimit,
     36 @ r3    const uint8_t *limit,
     37 @ sp    const uint8_t *thresh,
     38 @ r12   int count
     39 _mb_lpf_horizontal_edge:
     40 	mb_lpf_horizontal_edge: @ PROC
     41     push        {r4-r8, lr}
     42     vpush       {d8-d15}
     43     ldr         r4, [sp, #88]              @ load thresh
     44 
     45 h_count:
     46     vld1.8      {d16[]}, [r2]              @ load *blimit
     47     vld1.8      {d17[]}, [r3]              @ load *limit
     48     vld1.8      {d18[]}, [r4]              @ load *thresh
     49 
     50     sub         r8, r0, r1, lsl #3         @ move src pointer down by 8 lines
     51 
     52     vld1.u8     {d0}, [r8,:64], r1          @ p7
     53     vld1.u8     {d1}, [r8,:64], r1          @ p6
     54     vld1.u8     {d2}, [r8,:64], r1          @ p5
     55     vld1.u8     {d3}, [r8,:64], r1          @ p4
     56     vld1.u8     {d4}, [r8,:64], r1          @ p3
     57     vld1.u8     {d5}, [r8,:64], r1          @ p2
     58     vld1.u8     {d6}, [r8,:64], r1          @ p1
     59     vld1.u8     {d7}, [r8,:64], r1          @ p0
     60     vld1.u8     {d8}, [r8,:64], r1          @ q0
     61     vld1.u8     {d9}, [r8,:64], r1          @ q1
     62     vld1.u8     {d10}, [r8,:64], r1         @ q2
     63     vld1.u8     {d11}, [r8,:64], r1         @ q3
     64     vld1.u8     {d12}, [r8,:64], r1         @ q4
     65     vld1.u8     {d13}, [r8,:64], r1         @ q5
     66     vld1.u8     {d14}, [r8,:64], r1         @ q6
     67     vld1.u8     {d15}, [r8,:64], r1         @ q7
     68 
     69     bl          vpx_wide_mbfilter_neon
     70 
     71     tst         r7, #1
     72     beq         h_mbfilter
     73 
     74     @ flat && mask were not set for any of the channels. Just store the values
     75     @ from filter.
     76     sub         r8, r0, r1, lsl #1
     77 
     78     vst1.u8     {d25}, [r8,:64], r1         @ store op1
     79     vst1.u8     {d24}, [r8,:64], r1         @ store op0
     80     vst1.u8     {d23}, [r8,:64], r1         @ store oq0
     81     vst1.u8     {d26}, [r8,:64], r1         @ store oq1
     82 
     83     b           h_next
     84 
     85 h_mbfilter:
     86     tst         r7, #2
     87     beq         h_wide_mbfilter
     88 
     89     @ flat2 was not set for any of the channels. Just store the values from
     90     @ mbfilter.
     91     sub         r8, r0, r1, lsl #1
     92     sub         r8, r8, r1
     93 
     94     vst1.u8     {d18}, [r8,:64], r1         @ store op2
     95     vst1.u8     {d19}, [r8,:64], r1         @ store op1
     96     vst1.u8     {d20}, [r8,:64], r1         @ store op0
     97     vst1.u8     {d21}, [r8,:64], r1         @ store oq0
     98     vst1.u8     {d22}, [r8,:64], r1         @ store oq1
     99     vst1.u8     {d23}, [r8,:64], r1         @ store oq2
    100 
    101     b           h_next
    102 
    103 h_wide_mbfilter:
    104     sub         r8, r0, r1, lsl #3
    105     add         r8, r8, r1
    106 
    107     vst1.u8     {d16}, [r8,:64], r1         @ store op6
    108     vst1.u8     {d24}, [r8,:64], r1         @ store op5
    109     vst1.u8     {d25}, [r8,:64], r1         @ store op4
    110     vst1.u8     {d26}, [r8,:64], r1         @ store op3
    111     vst1.u8     {d27}, [r8,:64], r1         @ store op2
    112     vst1.u8     {d18}, [r8,:64], r1         @ store op1
    113     vst1.u8     {d19}, [r8,:64], r1         @ store op0
    114     vst1.u8     {d20}, [r8,:64], r1         @ store oq0
    115     vst1.u8     {d21}, [r8,:64], r1         @ store oq1
    116     vst1.u8     {d22}, [r8,:64], r1         @ store oq2
    117     vst1.u8     {d23}, [r8,:64], r1         @ store oq3
    118     vst1.u8     {d1}, [r8,:64], r1          @ store oq4
    119     vst1.u8     {d2}, [r8,:64], r1          @ store oq5
    120     vst1.u8     {d3}, [r8,:64], r1          @ store oq6
    121 
    122 h_next:
    123     add         r0, r0, #8
    124     subs        r12, r12, #1
    125     bne         h_count
    126 
    127     vpop        {d8-d15}
    128     pop         {r4-r8, pc}
    129 
    130 	.size mb_lpf_horizontal_edge, .-mb_lpf_horizontal_edge    @ ENDP        @ |mb_lpf_horizontal_edge|
    131 
    132 @ void vpx_lpf_horizontal_16_neon(uint8_t *s, int pitch,
    133 @                                     const uint8_t *blimit,
    134 @                                     const uint8_t *limit,
    135 @                                     const uint8_t *thresh)
    136 @ r0    uint8_t *s,
    137 @ r1    int pitch,
    138 @ r2    const uint8_t *blimit,
    139 @ r3    const uint8_t *limit,
    140 @ sp    const uint8_t *thresh
    141 _vpx_lpf_horizontal_16_neon:
    142 	vpx_lpf_horizontal_16_neon: @ PROC
    143     mov r12, #1
    144     b mb_lpf_horizontal_edge
    145 	.size vpx_lpf_horizontal_16_neon, .-vpx_lpf_horizontal_16_neon    @ ENDP        @ |vpx_lpf_horizontal_16_neon|
    146 
    147 @ void vpx_lpf_horizontal_16_dual_neon(uint8_t *s, int pitch,
    148 @                                      const uint8_t *blimit,
    149 @                                      const uint8_t *limit,
    150 @                                      const uint8_t *thresh)
    151 @ r0    uint8_t *s,
    152 @ r1    int pitch,
    153 @ r2    const uint8_t *blimit,
    154 @ r3    const uint8_t *limit,
    155 @ sp    const uint8_t *thresh
    156 _vpx_lpf_horizontal_16_dual_neon:
    157 	vpx_lpf_horizontal_16_dual_neon: @ PROC
    158     mov r12, #2
    159     b mb_lpf_horizontal_edge
    160 	.size vpx_lpf_horizontal_16_dual_neon, .-vpx_lpf_horizontal_16_dual_neon    @ ENDP        @ |vpx_lpf_horizontal_16_dual_neon|
    161 
    162 @ void mb_lpf_vertical_edge_w(uint8_t *s, int p, const uint8_t *blimit,
    163 @                             const uint8_t *limit, const uint8_t *thresh,
    164 @                             int count) {
    165 @ r0    uint8_t *s,
    166 @ r1    int p, /* pitch */
    167 @ r2    const uint8_t *blimit,
    168 @ r3    const uint8_t *limit,
    169 @ sp    const uint8_t *thresh,
    170 @ r12   int count
    171 _mb_lpf_vertical_edge_w:
    172 	mb_lpf_vertical_edge_w: @ PROC
    173     push        {r4-r8, lr}
    174     vpush       {d8-d15}
    175     ldr         r4, [sp, #88]              @ load thresh
    176 
    177 v_count:
    178     vld1.8      {d16[]}, [r2]              @ load *blimit
    179     vld1.8      {d17[]}, [r3]              @ load *limit
    180     vld1.8      {d18[]}, [r4]              @ load *thresh
    181 
    182     sub         r8, r0, #8
    183 
    184     vld1.8      {d0}, [r8,:64], r1
    185     vld1.8      {d8}, [r0,:64], r1
    186     vld1.8      {d1}, [r8,:64], r1
    187     vld1.8      {d9}, [r0,:64], r1
    188     vld1.8      {d2}, [r8,:64], r1
    189     vld1.8      {d10}, [r0,:64], r1
    190     vld1.8      {d3}, [r8,:64], r1
    191     vld1.8      {d11}, [r0,:64], r1
    192     vld1.8      {d4}, [r8,:64], r1
    193     vld1.8      {d12}, [r0,:64], r1
    194     vld1.8      {d5}, [r8,:64], r1
    195     vld1.8      {d13}, [r0,:64], r1
    196     vld1.8      {d6}, [r8,:64], r1
    197     vld1.8      {d14}, [r0,:64], r1
    198     vld1.8      {d7}, [r8,:64], r1
    199     vld1.8      {d15}, [r0,:64], r1
    200 
    201     sub         r0, r0, r1, lsl #3
    202 
    203     vtrn.32     q0, q2
    204     vtrn.32     q1, q3
    205     vtrn.32     q4, q6
    206     vtrn.32     q5, q7
    207 
    208     vtrn.16     q0, q1
    209     vtrn.16     q2, q3
    210     vtrn.16     q4, q5
    211     vtrn.16     q6, q7
    212 
    213     vtrn.8      d0, d1
    214     vtrn.8      d2, d3
    215     vtrn.8      d4, d5
    216     vtrn.8      d6, d7
    217 
    218     vtrn.8      d8, d9
    219     vtrn.8      d10, d11
    220     vtrn.8      d12, d13
    221     vtrn.8      d14, d15
    222 
    223     bl          vpx_wide_mbfilter_neon
    224 
    225     tst         r7, #1
    226     beq         v_mbfilter
    227 
    228     @ flat && mask were not set for any of the channels. Just store the values
    229     @ from filter.
    230     sub         r0, #2
    231 
    232     vswp        d23, d25
    233 
    234     vst4.8      {d23[0], d24[0], d25[0], d26[0]}, [r0], r1
    235     vst4.8      {d23[1], d24[1], d25[1], d26[1]}, [r0], r1
    236     vst4.8      {d23[2], d24[2], d25[2], d26[2]}, [r0], r1
    237     vst4.8      {d23[3], d24[3], d25[3], d26[3]}, [r0], r1
    238     vst4.8      {d23[4], d24[4], d25[4], d26[4]}, [r0], r1
    239     vst4.8      {d23[5], d24[5], d25[5], d26[5]}, [r0], r1
    240     vst4.8      {d23[6], d24[6], d25[6], d26[6]}, [r0], r1
    241     vst4.8      {d23[7], d24[7], d25[7], d26[7]}, [r0], r1
    242     add         r0, #2
    243 
    244     b           v_next
    245 
    246 v_mbfilter:
    247     tst         r7, #2
    248     beq         v_wide_mbfilter
    249 
    250     @ flat2 was not set for any of the channels. Just store the values from
    251     @ mbfilter.
    252     sub         r8, r0, #3
    253 
    254     vst3.8      {d18[0], d19[0], d20[0]}, [r8], r1
    255     vst3.8      {d21[0], d22[0], d23[0]}, [r0], r1
    256     vst3.8      {d18[1], d19[1], d20[1]}, [r8], r1
    257     vst3.8      {d21[1], d22[1], d23[1]}, [r0], r1
    258     vst3.8      {d18[2], d19[2], d20[2]}, [r8], r1
    259     vst3.8      {d21[2], d22[2], d23[2]}, [r0], r1
    260     vst3.8      {d18[3], d19[3], d20[3]}, [r8], r1
    261     vst3.8      {d21[3], d22[3], d23[3]}, [r0], r1
    262     vst3.8      {d18[4], d19[4], d20[4]}, [r8], r1
    263     vst3.8      {d21[4], d22[4], d23[4]}, [r0], r1
    264     vst3.8      {d18[5], d19[5], d20[5]}, [r8], r1
    265     vst3.8      {d21[5], d22[5], d23[5]}, [r0], r1
    266     vst3.8      {d18[6], d19[6], d20[6]}, [r8], r1
    267     vst3.8      {d21[6], d22[6], d23[6]}, [r0], r1
    268     vst3.8      {d18[7], d19[7], d20[7]}, [r8], r1
    269     vst3.8      {d21[7], d22[7], d23[7]}, [r0], r1
    270 
    271     b           v_next
    272 
    273 v_wide_mbfilter:
    274     sub         r8, r0, #8
    275 
    276     vtrn.32     d0,  d26
    277     vtrn.32     d16, d27
    278     vtrn.32     d24, d18
    279     vtrn.32     d25, d19
    280 
    281     vtrn.16     d0,  d24
    282     vtrn.16     d16, d25
    283     vtrn.16     d26, d18
    284     vtrn.16     d27, d19
    285 
    286     vtrn.8      d0,  d16
    287     vtrn.8      d24, d25
    288     vtrn.8      d26, d27
    289     vtrn.8      d18, d19
    290 
    291     vtrn.32     d20, d1
    292     vtrn.32     d21, d2
    293     vtrn.32     d22, d3
    294     vtrn.32     d23, d15
    295 
    296     vtrn.16     d20, d22
    297     vtrn.16     d21, d23
    298     vtrn.16     d1,  d3
    299     vtrn.16     d2,  d15
    300 
    301     vtrn.8      d20, d21
    302     vtrn.8      d22, d23
    303     vtrn.8      d1,  d2
    304     vtrn.8      d3,  d15
    305 
    306     vst1.8      {d0}, [r8,:64], r1
    307     vst1.8      {d20}, [r0,:64], r1
    308     vst1.8      {d16}, [r8,:64], r1
    309     vst1.8      {d21}, [r0,:64], r1
    310     vst1.8      {d24}, [r8,:64], r1
    311     vst1.8      {d22}, [r0,:64], r1
    312     vst1.8      {d25}, [r8,:64], r1
    313     vst1.8      {d23}, [r0,:64], r1
    314     vst1.8      {d26}, [r8,:64], r1
    315     vst1.8      {d1}, [r0,:64], r1
    316     vst1.8      {d27}, [r8,:64], r1
    317     vst1.8      {d2}, [r0,:64], r1
    318     vst1.8      {d18}, [r8,:64], r1
    319     vst1.8      {d3}, [r0,:64], r1
    320     vst1.8      {d19}, [r8,:64], r1
    321     vst1.8      {d15}, [r0,:64], r1
    322 
    323 v_next:
    324     subs        r12, #1
    325     bne         v_count
    326 
    327     vpop        {d8-d15}
    328     pop         {r4-r8, pc}
    329 
    330 	.size mb_lpf_vertical_edge_w, .-mb_lpf_vertical_edge_w    @ ENDP        @ |mb_lpf_vertical_edge_w|
    331 
    332 @ void vpx_lpf_vertical_16_neon(uint8_t *s, int p, const uint8_t *blimit,
    333 @                               const uint8_t *limit, const uint8_t *thresh)
    334 @ r0    uint8_t *s,
    335 @ r1    int p, /* pitch */
    336 @ r2    const uint8_t *blimit,
    337 @ r3    const uint8_t *limit,
    338 @ sp    const uint8_t *thresh
    339 _vpx_lpf_vertical_16_neon:
    340 	vpx_lpf_vertical_16_neon: @ PROC
    341     mov r12, #1
    342     b mb_lpf_vertical_edge_w
    343 	.size vpx_lpf_vertical_16_neon, .-vpx_lpf_vertical_16_neon    @ ENDP        @ |vpx_lpf_vertical_16_neon|
    344 
    345 @ void vpx_lpf_vertical_16_dual_neon(uint8_t *s, int p, const uint8_t *blimit,
    346 @                                    const uint8_t *limit,
    347 @                                    const uint8_t *thresh)
    348 @ r0    uint8_t *s,
    349 @ r1    int p, /* pitch */
    350 @ r2    const uint8_t *blimit,
    351 @ r3    const uint8_t *limit,
    352 @ sp    const uint8_t *thresh
    353 _vpx_lpf_vertical_16_dual_neon:
    354 	vpx_lpf_vertical_16_dual_neon: @ PROC
    355     mov r12, #2
    356     b mb_lpf_vertical_edge_w
    357 	.size vpx_lpf_vertical_16_dual_neon, .-vpx_lpf_vertical_16_dual_neon    @ ENDP        @ |vpx_lpf_vertical_16_dual_neon|
    358 
    359 @ void vpx_wide_mbfilter_neon();
    360 @ This is a helper function for the loopfilters. The invidual functions do the
    361 @ necessary load, transpose (if necessary) and store.
    362 @
    363 @ r0-r3 PRESERVE
    364 @ d16    blimit
    365 @ d17    limit
    366 @ d18    thresh
    367 @ d0    p7
    368 @ d1    p6
    369 @ d2    p5
    370 @ d3    p4
    371 @ d4    p3
    372 @ d5    p2
    373 @ d6    p1
    374 @ d7    p0
    375 @ d8    q0
    376 @ d9    q1
    377 @ d10   q2
    378 @ d11   q3
    379 @ d12   q4
    380 @ d13   q5
    381 @ d14   q6
    382 @ d15   q7
    383 _vpx_wide_mbfilter_neon:
    384 	vpx_wide_mbfilter_neon: @ PROC
    385     mov         r7, #0
    386 
    387     @ filter_mask
    388     vabd.u8     d19, d4, d5                @ abs(p3 - p2)
    389     vabd.u8     d20, d5, d6                @ abs(p2 - p1)
    390     vabd.u8     d21, d6, d7                @ abs(p1 - p0)
    391     vabd.u8     d22, d9, d8                @ abs(q1 - q0)
    392     vabd.u8     d23, d10, d9               @ abs(q2 - q1)
    393     vabd.u8     d24, d11, d10              @ abs(q3 - q2)
    394 
    395     @ only compare the largest value to limit
    396     vmax.u8     d19, d19, d20              @ max(abs(p3 - p2), abs(p2 - p1))
    397     vmax.u8     d20, d21, d22              @ max(abs(p1 - p0), abs(q1 - q0))
    398     vmax.u8     d23, d23, d24              @ max(abs(q2 - q1), abs(q3 - q2))
    399     vmax.u8     d19, d19, d20
    400 
    401     vabd.u8     d24, d7, d8                @ abs(p0 - q0)
    402 
    403     vmax.u8     d19, d19, d23
    404 
    405     vabd.u8     d23, d6, d9                @ a = abs(p1 - q1)
    406     vqadd.u8    d24, d24, d24              @ b = abs(p0 - q0) * 2
    407 
    408     @ abs () > limit
    409     vcge.u8     d19, d17, d19
    410 
    411     @ flatmask4
    412     vabd.u8     d25, d7, d5                @ abs(p0 - p2)
    413     vabd.u8     d26, d8, d10               @ abs(q0 - q2)
    414     vabd.u8     d27, d4, d7                @ abs(p3 - p0)
    415     vabd.u8     d28, d11, d8               @ abs(q3 - q0)
    416 
    417     @ only compare the largest value to thresh
    418     vmax.u8     d25, d25, d26              @ max(abs(p0 - p2), abs(q0 - q2))
    419     vmax.u8     d26, d27, d28              @ max(abs(p3 - p0), abs(q3 - q0))
    420     vmax.u8     d25, d25, d26
    421     vmax.u8     d20, d20, d25
    422 
    423     vshr.u8     d23, d23, #1               @ a = a / 2
    424     vqadd.u8    d24, d24, d23              @ a = b + a
    425 
    426     vmov.u8     d30, #1
    427     vcge.u8     d24, d16, d24              @ (a > blimit * 2 + limit) * -1
    428 
    429     vcge.u8     d20, d30, d20              @ flat
    430 
    431     vand        d19, d19, d24              @ mask
    432 
    433     @ hevmask
    434     vcgt.u8     d21, d21, d18              @ (abs(p1 - p0) > thresh)*-1
    435     vcgt.u8     d22, d22, d18              @ (abs(q1 - q0) > thresh)*-1
    436     vorr        d21, d21, d22              @ hev
    437 
    438     vand        d16, d20, d19              @ flat && mask
    439     vmov        r5, r6, d16
    440 
    441     @ flatmask5(1, p7, p6, p5, p4, p0, q0, q4, q5, q6, q7)
    442     vabd.u8     d22, d3, d7                @ abs(p4 - p0)
    443     vabd.u8     d23, d12, d8               @ abs(q4 - q0)
    444     vabd.u8     d24, d7, d2                @ abs(p0 - p5)
    445     vabd.u8     d25, d8, d13               @ abs(q0 - q5)
    446     vabd.u8     d26, d1, d7                @ abs(p6 - p0)
    447     vabd.u8     d27, d14, d8               @ abs(q6 - q0)
    448     vabd.u8     d28, d0, d7                @ abs(p7 - p0)
    449     vabd.u8     d29, d15, d8               @ abs(q7 - q0)
    450 
    451     @ only compare the largest value to thresh
    452     vmax.u8     d22, d22, d23              @ max(abs(p4 - p0), abs(q4 - q0))
    453     vmax.u8     d23, d24, d25              @ max(abs(p0 - p5), abs(q0 - q5))
    454     vmax.u8     d24, d26, d27              @ max(abs(p6 - p0), abs(q6 - q0))
    455     vmax.u8     d25, d28, d29              @ max(abs(p7 - p0), abs(q7 - q0))
    456 
    457     vmax.u8     d26, d22, d23
    458     vmax.u8     d27, d24, d25
    459     vmax.u8     d23, d26, d27
    460 
    461     vcge.u8     d18, d30, d23              @ flat2
    462 
    463     vmov.u8     d22, #0x80
    464 
    465     orrs        r5, r5, r6                 @ Check for 0
    466     orreq       r7, r7, #1                 @ Only do filter branch
    467 
    468     vand        d17, d18, d16              @ flat2 && flat && mask
    469     vmov        r5, r6, d17
    470 
    471     @ mbfilter() function
    472 
    473     @ filter() function
    474     @ convert to signed
    475     veor        d23, d8, d22               @ qs0
    476     veor        d24, d7, d22               @ ps0
    477     veor        d25, d6, d22               @ ps1
    478     veor        d26, d9, d22               @ qs1
    479 
    480     vmov.u8     d27, #3
    481 
    482     vsub.s8     d28, d23, d24              @ ( qs0 - ps0)
    483     vqsub.s8    d29, d25, d26              @ filter = clamp(ps1-qs1)
    484     vmull.s8    q15, d28, d27              @ 3 * ( qs0 - ps0)
    485     vand        d29, d29, d21              @ filter &= hev
    486     vaddw.s8    q15, q15, d29              @ filter + 3 * (qs0 - ps0)
    487     vmov.u8     d29, #4
    488 
    489     @ filter = clamp(filter + 3 * ( qs0 - ps0))
    490     vqmovn.s16  d28, q15
    491 
    492     vand        d28, d28, d19              @ filter &= mask
    493 
    494     vqadd.s8    d30, d28, d27              @ filter2 = clamp(filter+3)
    495     vqadd.s8    d29, d28, d29              @ filter1 = clamp(filter+4)
    496     vshr.s8     d30, d30, #3               @ filter2 >>= 3
    497     vshr.s8     d29, d29, #3               @ filter1 >>= 3
    498 
    499 
    500     vqadd.s8    d24, d24, d30              @ op0 = clamp(ps0 + filter2)
    501     vqsub.s8    d23, d23, d29              @ oq0 = clamp(qs0 - filter1)
    502 
    503     @ outer tap adjustments: ++filter1 >> 1
    504     vrshr.s8    d29, d29, #1
    505     vbic        d29, d29, d21              @ filter &= ~hev
    506 
    507     vqadd.s8    d25, d25, d29              @ op1 = clamp(ps1 + filter)
    508     vqsub.s8    d26, d26, d29              @ oq1 = clamp(qs1 - filter)
    509 
    510     veor        d24, d24, d22              @ *f_op0 = u^0x80
    511     veor        d23, d23, d22              @ *f_oq0 = u^0x80
    512     veor        d25, d25, d22              @ *f_op1 = u^0x80
    513     veor        d26, d26, d22              @ *f_oq1 = u^0x80
    514 
    515     tst         r7, #1
    516     bxne        lr
    517 
    518     orrs        r5, r5, r6                 @ Check for 0
    519     orreq       r7, r7, #2                 @ Only do mbfilter branch
    520 
    521     @ mbfilter flat && mask branch
    522     @ TODO(fgalligan): Can I decrease the cycles shifting to consective d's
    523     @ and using vibt on the q's?
    524     vmov.u8     d29, #2
    525     vaddl.u8    q15, d7, d8                @ op2 = p0 + q0
    526     vmlal.u8    q15, d4, d27               @ op2 = p0 + q0 + p3 * 3
    527     vmlal.u8    q15, d5, d29               @ op2 = p0 + q0 + p3 * 3 + p2 * 2
    528     vaddl.u8    q10, d4, d5
    529     vaddw.u8    q15, d6                    @ op2=p1 + p0 + q0 + p3 * 3 + p2 *2
    530     vaddl.u8    q14, d6, d9
    531     vqrshrn.u16 d18, q15, #3               @ r_op2
    532 
    533     vsub.i16    q15, q10
    534     vaddl.u8    q10, d4, d6
    535     vadd.i16    q15, q14
    536     vaddl.u8    q14, d7, d10
    537     vqrshrn.u16 d19, q15, #3               @ r_op1
    538 
    539     vsub.i16    q15, q10
    540     vadd.i16    q15, q14
    541     vaddl.u8    q14, d8, d11
    542     vqrshrn.u16 d20, q15, #3               @ r_op0
    543 
    544     vsubw.u8    q15, d4                    @ oq0 = op0 - p3
    545     vsubw.u8    q15, d7                    @ oq0 -= p0
    546     vadd.i16    q15, q14
    547     vaddl.u8    q14, d9, d11
    548     vqrshrn.u16 d21, q15, #3               @ r_oq0
    549 
    550     vsubw.u8    q15, d5                    @ oq1 = oq0 - p2
    551     vsubw.u8    q15, d8                    @ oq1 -= q0
    552     vadd.i16    q15, q14
    553     vaddl.u8    q14, d10, d11
    554     vqrshrn.u16 d22, q15, #3               @ r_oq1
    555 
    556     vsubw.u8    q15, d6                    @ oq2 = oq0 - p1
    557     vsubw.u8    q15, d9                    @ oq2 -= q1
    558     vadd.i16    q15, q14
    559     vqrshrn.u16 d27, q15, #3               @ r_oq2
    560 
    561     @ Filter does not set op2 or oq2, so use p2 and q2.
    562     vbif        d18, d5, d16               @ t_op2 |= p2 & ~(flat & mask)
    563     vbif        d19, d25, d16              @ t_op1 |= f_op1 & ~(flat & mask)
    564     vbif        d20, d24, d16              @ t_op0 |= f_op0 & ~(flat & mask)
    565     vbif        d21, d23, d16              @ t_oq0 |= f_oq0 & ~(flat & mask)
    566     vbif        d22, d26, d16              @ t_oq1 |= f_oq1 & ~(flat & mask)
    567 
    568     vbit        d23, d27, d16              @ t_oq2 |= r_oq2 & (flat & mask)
    569     vbif        d23, d10, d16              @ t_oq2 |= q2 & ~(flat & mask)
    570 
    571     tst         r7, #2
    572     bxne        lr
    573 
    574     @ wide_mbfilter flat2 && flat && mask branch
    575     vmov.u8     d16, #7
    576     vaddl.u8    q15, d7, d8                @ op6 = p0 + q0
    577     vaddl.u8    q12, d2, d3
    578     vaddl.u8    q13, d4, d5
    579     vaddl.u8    q14, d1, d6
    580     vmlal.u8    q15, d0, d16               @ op6 += p7 * 3
    581     vadd.i16    q12, q13
    582     vadd.i16    q15, q14
    583     vaddl.u8    q14, d2, d9
    584     vadd.i16    q15, q12
    585     vaddl.u8    q12, d0, d1
    586     vaddw.u8    q15, d1
    587     vaddl.u8    q13, d0, d2
    588     vadd.i16    q14, q15, q14
    589     vqrshrn.u16 d16, q15, #4               @ w_op6
    590 
    591     vsub.i16    q15, q14, q12
    592     vaddl.u8    q14, d3, d10
    593     vqrshrn.u16 d24, q15, #4               @ w_op5
    594 
    595     vsub.i16    q15, q13
    596     vaddl.u8    q13, d0, d3
    597     vadd.i16    q15, q14
    598     vaddl.u8    q14, d4, d11
    599     vqrshrn.u16 d25, q15, #4               @ w_op4
    600 
    601     vadd.i16    q15, q14
    602     vaddl.u8    q14, d0, d4
    603     vsub.i16    q15, q13
    604     vsub.i16    q14, q15, q14
    605     vqrshrn.u16 d26, q15, #4               @ w_op3
    606 
    607     vaddw.u8    q15, q14, d5               @ op2 += p2
    608     vaddl.u8    q14, d0, d5
    609     vaddw.u8    q15, d12                   @ op2 += q4
    610     vbif        d26, d4, d17               @ op3 |= p3 & ~(f2 & f & m)
    611     vqrshrn.u16 d27, q15, #4               @ w_op2
    612 
    613     vsub.i16    q15, q14
    614     vaddl.u8    q14, d0, d6
    615     vaddw.u8    q15, d6                    @ op1 += p1
    616     vaddw.u8    q15, d13                   @ op1 += q5
    617     vbif        d27, d18, d17              @ op2 |= t_op2 & ~(f2 & f & m)
    618     vqrshrn.u16 d18, q15, #4               @ w_op1
    619 
    620     vsub.i16    q15, q14
    621     vaddl.u8    q14, d0, d7
    622     vaddw.u8    q15, d7                    @ op0 += p0
    623     vaddw.u8    q15, d14                   @ op0 += q6
    624     vbif        d18, d19, d17              @ op1 |= t_op1 & ~(f2 & f & m)
    625     vqrshrn.u16 d19, q15, #4               @ w_op0
    626 
    627     vsub.i16    q15, q14
    628     vaddl.u8    q14, d1, d8
    629     vaddw.u8    q15, d8                    @ oq0 += q0
    630     vaddw.u8    q15, d15                   @ oq0 += q7
    631     vbif        d19, d20, d17              @ op0 |= t_op0 & ~(f2 & f & m)
    632     vqrshrn.u16 d20, q15, #4               @ w_oq0
    633 
    634     vsub.i16    q15, q14
    635     vaddl.u8    q14, d2, d9
    636     vaddw.u8    q15, d9                    @ oq1 += q1
    637     vaddl.u8    q4, d10, d15
    638     vaddw.u8    q15, d15                   @ oq1 += q7
    639     vbif        d20, d21, d17              @ oq0 |= t_oq0 & ~(f2 & f & m)
    640     vqrshrn.u16 d21, q15, #4               @ w_oq1
    641 
    642     vsub.i16    q15, q14
    643     vaddl.u8    q14, d3, d10
    644     vadd.i16    q15, q4
    645     vaddl.u8    q4, d11, d15
    646     vbif        d21, d22, d17              @ oq1 |= t_oq1 & ~(f2 & f & m)
    647     vqrshrn.u16 d22, q15, #4               @ w_oq2
    648 
    649     vsub.i16    q15, q14
    650     vaddl.u8    q14, d4, d11
    651     vadd.i16    q15, q4
    652     vaddl.u8    q4, d12, d15
    653     vbif        d22, d23, d17              @ oq2 |= t_oq2 & ~(f2 & f & m)
    654     vqrshrn.u16 d23, q15, #4               @ w_oq3
    655 
    656     vsub.i16    q15, q14
    657     vaddl.u8    q14, d5, d12
    658     vadd.i16    q15, q4
    659     vaddl.u8    q4, d13, d15
    660     vbif        d16, d1, d17               @ op6 |= p6 & ~(f2 & f & m)
    661     vqrshrn.u16 d1, q15, #4                @ w_oq4
    662 
    663     vsub.i16    q15, q14
    664     vaddl.u8    q14, d6, d13
    665     vadd.i16    q15, q4
    666     vaddl.u8    q4, d14, d15
    667     vbif        d24, d2, d17               @ op5 |= p5 & ~(f2 & f & m)
    668     vqrshrn.u16 d2, q15, #4                @ w_oq5
    669 
    670     vsub.i16    q15, q14
    671     vbif        d25, d3, d17               @ op4 |= p4 & ~(f2 & f & m)
    672     vadd.i16    q15, q4
    673     vbif        d23, d11, d17              @ oq3 |= q3 & ~(f2 & f & m)
    674     vqrshrn.u16 d3, q15, #4                @ w_oq6
    675     vbif        d1, d12, d17               @ oq4 |= q4 & ~(f2 & f & m)
    676     vbif        d2, d13, d17               @ oq5 |= q5 & ~(f2 & f & m)
    677     vbif        d3, d14, d17               @ oq6 |= q6 & ~(f2 & f & m)
    678 
    679     bx          lr
    680 	.size vpx_wide_mbfilter_neon, .-vpx_wide_mbfilter_neon    @ ENDP        @ |vpx_wide_mbfilter_neon|
    681 
    682 	.section	.note.GNU-stack,"",%progbits
    683